1 // cmdlib.c
2 
3 #include "cmdlib.h"
4 #include "qcc.h"
5 
6 #ifdef WIN32
7 #ifdef WIN32GUI
8 #include <windows.h>
9 #endif
10 
11 #else
12 #include <sys/time.h>
13 #endif
14 
15 #define PATHSEPERATOR   '\\'
16 
17 
18 // set these before calling CheckParm
19 int myargc;
20 char **myargv;
21 
22 char	com_token[1024];
23 int		com_eof;
24 /*
25 ============
26 va
27 
28 does a varargs printf into a temp buffer, so I don't need to have
29 varargs versions of all text functions.
30 FIXME: make this buffer size safe someday
31 ============
32 */
va(char * format,...)33 char    *va(char *format, ...)
34 {
35 	va_list         argptr;
36 	static char             string[1024];
37 
38 	va_start (argptr, format);
39 	vsprintf (string, format,argptr);
40 	va_end (argptr);
41 
42 	return string;
43 }
44 /*
45 ================
46 I_FloatTime
47 ================
48 */
49 #include <time.h>
50 
I_FloatTime(void)51 time_t I_FloatTime (void)
52 {
53     time_t t;
54 
55     time(&t);
56 
57     return t;
58 
59 
60 }
61 
62 
63 /*
64 ==============
65 COM_Parse
66 
67 Parse a token out of a string
68 ==============
69 */
COM_Parse(char * data)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 		if (!*data)
99 		{
100 			com_eof = true;
101 			return NULL;			// end of file;
102 		}
103 		goto skipwhite;
104 	}
105 // skip /* */ comments
106 	if (c=='/' && data[1] == '*')
107 	{
108 		data+= 2; // don't fall for /*/
109 		while (*data && !(*data == '*' && data[1] == '/'))
110 			data++;
111 		if (!*data)
112 		{
113 			com_eof = true;
114 			return NULL;			// end of file;
115 		}
116 		data+=2;
117 		goto skipwhite;
118 	}
119 // handle quoted strings specially
120 	if (c == '\"')
121 	{
122 		data++;
123 		do
124 		{
125 			c = *data++;
126 			if (c=='\"')
127 			{
128 				com_token[len] = 0;
129 				return data;
130 			}
131 			com_token[len] = c;
132 			len++;
133 		} while (1);
134 	}
135 
136 // parse single characters
137 	if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c==':')
138 	{
139 		com_token[len] = c;
140 		len++;
141 		com_token[len] = 0;
142 		return data+1;
143 	}
144 
145 // parse a regular word
146 	do
147 	{
148 		com_token[len] = c;
149 		data++;
150 		len++;
151 		c = *data;
152 	if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c==':')
153 			break;
154 	} while (c>32);
155 
156 	com_token[len] = 0;
157 	return data;
158 }
159 
160 
161 
162 
163 /*
164 ================
165 filelength
166 ================
167 */
168 #ifndef WIN32
filelength(int handle)169 int filelength (int handle)
170 {
171 	struct stat	fileinfo;
172 
173 	if (fstat (handle,&fileinfo) == -1)
174 	{
175 		Sys_Error ("Error fstating");
176 	}
177 
178 	return fileinfo.st_size;
179 }
180 
tell(int handle)181 int tell (int handle)
182 {
183 	return lseek (handle, 0, SEEK_CUR);
184 }
185 #endif
186 
strupr(char * start)187 char *strupr (char *start)
188 {
189 	char	*in;
190 	in = start;
191 	while (*in)
192 	{
193 		*in = toupper(*in);
194 		in++;
195 	}
196 	return start;
197 }
198 
strlower(char * start)199 char *strlower (char *start)
200 {
201 	char	*in;
202 	in = start;
203 	while (*in)
204 	{
205 		*in = tolower(*in);
206 		in++;
207 	}
208 	return start;
209 }
210 
211 
212 /*
213 =============================================================================
214 
215 						MISC FUNCTIONS
216 
217 =============================================================================
218 */
219 
220 #ifdef WIN32GUI
221 extern HWND main_hWnd;
222 char summary_buf[4096];
223 extern int compiled;
224 
225 #endif
226 
227 
228 /*
229 =================
230 Sys_Error
231 
232 For abnormal program terminations
233 =================
234 */
235 
236 
Sys_Error(char * error,...)237 void Sys_Error (char *error, ...)
238 {
239 	va_list argptr;
240 	char		text[1024];
241 	va_start (argptr, error);
242 	vsprintf (text, error,argptr);
243 	va_end (argptr);
244 #ifdef macintosh
245 	Error(text);
246 	exit(0);
247 #endif
248 #ifdef WIN32GUI
249 	MessageBox(main_hWnd, text, "FrikDec Error", MB_OK | MB_SETFOREGROUND | MB_ICONSTOP);
250 	exit(0);
251 #else
252 	printf ("************ ERROR ***********\n");
253 	printf("%s\n", text);
254 	exit(0);
255 #endif
256 }
257 
Q_strcmp(char * s1,char * s2)258 int Q_strcmp (char *s1, char *s2)
259 {
260 	while (1)
261 	{
262 		if (*s1 != *s2)
263 			return -1;              // strings not equal
264 		if (!*s1)
265 			return 0;               // strings are equal
266 		s1++;
267 		s2++;
268 	}
269 
270 	return -1;
271 }
272 /*
273 =================
274 CheckParm
275 
276 Checks for the given parameter in the program's command line arguments
277 Returns the argument number (1 to argc-1) or 0 if not present
278 =================
279 */
CheckParm(char * check)280 int CheckParm (char *check)
281 {
282 	int             i;
283 
284 	for (i = 1;i<myargc;i++)
285 	{
286 
287 		if ( !Q_strcmp(check, myargv[i]) )
288 			return i;
289 
290 	}
291 
292 	return 0;
293 }
294 
295 
296 
SafeOpenWrite(char * filename)297 int SafeOpenWrite (char *filename)
298 {
299 	int     handle;
300 
301 	umask (0);
302 
303 	handle = open(filename,O_WRONLY | O_CREAT | O_TRUNC | O_BINARY
304 	, 0666);
305 
306 	if (handle == -1)
307 		Sys_Error ("Error opening %s: %s",filename,strerror(errno));
308 
309 	return handle;
310 }
311 
SafeOpenRead(char * filename)312 int SafeOpenRead (char *filename)
313 {
314 	int     handle;
315 
316 	handle = open(filename,O_RDONLY | O_BINARY);
317 
318 	if (handle <= 0)
319 		Sys_Error ("Error opening %s: %s",filename,strerror(errno));
320 
321 	return handle;
322 }
323 
324 
SafeRead(int handle,void * buffer,long count)325 void SafeRead (int handle, void *buffer, long count)
326 {
327 	if (read (handle,buffer,count) != count)
328 		Sys_Error ("File read failure");
329 }
330 
331 
SafeWrite(int handle,void * buffer,long count)332 void SafeWrite (int handle, void *buffer, long count)
333 {
334 	if (write (handle,buffer,count) != count)
335 		Sys_Error ("File write failure");
336 }
337 
338 
339 
340 /*
341 ==============
342 LoadFile
343 ==============
344 */
LoadFile(char * filename,void ** bufferptr)345 long    LoadFile (char *filename, void **bufferptr)
346 {
347 	int             handle;
348 	long    length;
349 	void    *buffer;
350 
351 	handle = SafeOpenRead (filename);
352 	length = filelength (handle);
353 	buffer = malloc(length+1);
354 	((byte *)buffer)[length] = 0;
355 	SafeRead (handle, buffer, length);
356 	close (handle);
357 
358 	*bufferptr = buffer;
359 	return length;
360 }
361 
362 
363 /*
364 ==============
365 SaveFile
366 ==============
367 */
SaveFile(char * filename,void * buffer,long count)368 void    SaveFile (char *filename, void *buffer, long count)
369 {
370 	int             handle;
371 
372 	handle = SafeOpenWrite (filename);
373 	SafeWrite (handle, buffer, count);
374 	close (handle);
375 }
376 
377 
378 
DefaultExtension(char * path,char * extension)379 void DefaultExtension (char *path, char *extension)
380 {
381 	char    *src;
382 //
383 // if path doesn't have a .EXT, append extension
384 // (extension should include the .)
385 //
386 	src = path + strlen(path) - 1;
387 
388 	while (*src != PATHSEPERATOR && src != path)
389 	{
390 		if (*src == '.')
391 			return;                 // it has an extension
392 		src--;
393 	}
394 
395 	strcat (path, extension);
396 }
397 
398 
DefaultPath(char * path,char * basepath)399 void DefaultPath (char *path, char *basepath)
400 {
401 	char    temp[128];
402 
403 	if (path[0] == PATHSEPERATOR)
404 		return;                   // absolute path location
405 	strcpy (temp,path);
406 	strcpy (path,basepath);
407 	strcat (path,temp);
408 }
409 
410 
StripFilename(char * path)411 void    StripFilename (char *path)
412 {
413 	int             length;
414 
415 	length = strlen(path)-1;
416 	while (length > 0 && path[length] != PATHSEPERATOR)
417 		length--;
418 	path[length] = 0;
419 }
420 
StripExtension(char * path)421 void    StripExtension (char *path)
422 {
423 	int             length;
424 
425 	length = strlen(path)-1;
426 	while (length > 0 && path[length] != '.')
427 	{
428 		length--;
429 		if (path[length] == '/')
430 			return;		// no extension
431 	}
432 	if (length)
433 		path[length] = 0;
434 }
435 
436 
ExtractFilename(char * path,char * dest)437 void ExtractFilename (char *path, char *dest)
438 {
439 	char    *src;
440 
441 	src = path + strlen(path) - 1;
442 
443 //
444 // back up until a \ or the start
445 //
446 	while (src > path && *(src-1) != PATHSEPERATOR)
447 		src--;
448 
449 
450 	strcpy (dest,src);
451 }
452 
453 
454 
455 /*
456 ==============
457 ParseNum / ParseHex
458 ==============
459 */
ParseHex(char * hex)460 long ParseHex (char *hex)
461 {
462 	char    *str;
463 	long    num;
464 
465 	num = 0;
466 	str = hex;
467 
468 	while (*str)
469 	{
470 		num <<= 4;
471 		if (*str >= '0' && *str <= '9')
472 			num += *str-'0';
473 		else if (*str >= 'a' && *str <= 'f')
474 			num += 10 + *str-'a';
475 		else if (*str >= 'A' && *str <= 'F')
476 			num += 10 + *str-'A';
477 		else
478 			Sys_Error ("Bad hex number: %s",hex);
479 		str++;
480 	}
481 
482 	return num;
483 }
484 
485 
ParseNum(char * str)486 long ParseNum (char *str)
487 {
488 	if (str[0] == '$')
489 		return ParseHex (str+1);
490 	if (str[0] == '0' && str[1] == 'x')
491 		return ParseHex (str+2);
492 	return atol (str);
493 }
494 
495 
496 
497 /*
498 ============================================================================
499 
500 					BYTE ORDER FUNCTIONS
501 
502 ============================================================================
503 */
504 
505 #ifndef INLINE
506 
507 #ifdef __BIG_ENDIAN__
508 
LittleShort(short l)509 short   LittleShort (short l)
510 {
511 	byte    b1,b2;
512 
513 	b1 = l&255;
514 	b2 = (l>>8)&255;
515 
516 	return (b1<<8) + b2;
517 }
518 
BigShort(short l)519 short   BigShort (short l)
520 {
521 	return l;
522 }
523 
LittleLong(long l)524 long    LittleLong (long l)
525 {
526 	byte    b1,b2,b3,b4;
527 
528 	b1 = l&255;
529 	b2 = (l>>8)&255;
530 	b3 = (l>>16)&255;
531 	b4 = (l>>24)&255;
532 
533 	return ((long)b1<<24) + ((long)b2<<16) + ((long)b3<<8) + b4;
534 }
535 
BigLong(long l)536 long    BigLong (long l)
537 {
538 	return l;
539 }
540 
541 
LittleFloat(float l)542 float	LittleFloat (float l)
543 {
544 	union {byte b[4]; float f;} in, out;
545 
546 	in.f = l;
547 	out.b[0] = in.b[3];
548 	out.b[1] = in.b[2];
549 	out.b[2] = in.b[1];
550 	out.b[3] = in.b[0];
551 
552 	return out.f;
553 }
554 
BigFloat(float l)555 float	BigFloat (float l)
556 {
557 	return l;
558 }
559 
560 
561 #else
562 
563 
BigShort(short l)564 short   BigShort (short l)
565 {
566 	byte    b1,b2;
567 
568 	b1 = l&255;
569 	b2 = (l>>8)&255;
570 
571 	return (b1<<8) + b2;
572 }
573 
LittleShort(short l)574 short   LittleShort (short l)
575 {
576 	return l;
577 }
578 
579 
BigLong(long l)580 long    BigLong (long l)
581 {
582 	byte    b1,b2,b3,b4;
583 
584 	b1 = l&255;
585 	b2 = (l>>8)&255;
586 	b3 = (l>>16)&255;
587 	b4 = (l>>24)&255;
588 
589 	return ((long)b1<<24) + ((long)b2<<16) + ((long)b3<<8) + b4;
590 }
591 
LittleLong(long l)592 long    LittleLong (long l)
593 {
594 	return l;
595 }
596 
BigFloat(float l)597 float	BigFloat (float l)
598 {
599 	union {byte b[4]; float f;} in, out;
600 
601 	in.f = l;
602 	out.b[0] = in.b[3];
603 	out.b[1] = in.b[2];
604 	out.b[2] = in.b[1];
605 	out.b[3] = in.b[0];
606 
607 	return out.f;
608 }
609 
LittleFloat(float l)610 float	LittleFloat (float l)
611 {
612 	return l;
613 }
614 
615 #endif
616 
617 #endif
618