5 //#include <sys/time.h>
7 #define PATHSEPERATOR '/'
10 extern jmp_buf qcccompileerror;
13 // set these before calling CheckParm
20 const unsigned int type_size[12] = {1, //void
21 sizeof(string_t)/4, //string
26 sizeof(func_t)/4,//function
27 1, //pointer (its an int index)
29 1, //fixme: how big should a variant be?
30 0, //ev_struct. variable sized.
31 0 //ev_union. variable sized.
35 ============================================================================
39 ============================================================================
41 short (*PRBigShort) (short l);
42 short (*PRLittleShort) (short l);
43 int (*PRBigLong) (int l);
44 int (*PRLittleLong) (int l);
45 float (*PRBigFloat) (float l);
46 float (*PRLittleFloat) (float l);
49 short QCC_SwapShort (short l)
59 short QCC_Short (short l)
65 int QCC_SwapLong (int l)
74 return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4;
83 float QCC_SwapFloat (float l)
85 union {qbyte b[4]; float f;} in, out;
96 float QCC_Float (float l)
103 union {qbyte b[2]; unsigned short s;} ed;
107 PRBigShort = QCC_SwapShort;
108 PRLittleShort = QCC_Short;
109 PRBigLong = QCC_SwapLong;
110 PRLittleLong = QCC_Long;
111 PRBigFloat = QCC_SwapFloat;
112 PRLittleFloat = QCC_Float;
116 PRBigShort = QCC_Short;
117 PRLittleShort = QCC_SwapShort;
118 PRBigLong = QCC_Long;
119 PRLittleLong = QCC_SwapLong;
120 PRBigFloat = QCC_Float;
121 PRLittleFloat = QCC_SwapFloat;
134 double I_FloatTime (void)
140 gettimeofday(&tp, &tzp);
145 return tp.tv_usec/1000000.0;
148 return (tp.tv_sec - secbase) + tp.tv_usec/1000000.0;
155 int QC_strncasecmp (const char *s1, const char *s2, int n)
165 return 0; // strings are equal until end point
169 if (c1 >= 'a' && c1 <= 'z')
171 if (c2 >= 'a' && c2 <= 'z')
174 return -1; // strings not equal
177 return 0; // strings are equal
185 int QC_strcasecmp (const char *s1, const char *s2)
187 return QC_strncasecmp(s1, s2, 0x7fffffff);
191 int QC_strncasecmp(const char *s1, const char *s2, int n);
192 int QC_strcasecmp (const char *s1, const char *s2)
194 return QC_strncasecmp(s1, s2, 0x7fffffff);
206 Parse a token out of a string
209 char *QCC_COM_Parse (char *data)
222 while ( (c = *data) <= ' ')
227 return NULL; // end of file;
233 if (c=='/' && data[1] == '/')
235 while (*data && *data != '\n')
241 if (c=='/' && data[1] == '*')
243 while (data[1] && (data[0] != '*' || data[1] != '/'))
250 // handle quoted strings specially
257 if (c=='\\' && *data == '\"')
258 c = *data++; //allow C-style string escapes
259 else if (c=='\\' && *data == '\\')
260 c = *data++; // \ is now a special character so it needs to be marked up using itself
261 else if (c=='\\' && *data == 'n')
262 { // and do new lines while we're at it.
271 else if (c=='\0'||c=='\n')
281 // parse single characters
282 if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c==':' || c==',')
290 // parse a regular word
297 if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c==':' || c=='\"' || c==',')
306 char *QCC_COM_Parse2 (char *data)
319 while ( (c = *data) <= ' ')
324 return NULL; // end of file;
330 if (c=='/' && data[1] == '/')
332 while (*data && *data != '\n')
338 // handle quoted strings specially
345 if (c=='\\' && *data == '\"')
346 c = *data++; //allow C-style string escapes
347 else if (c=='\\' && *data == '\\')
348 c = *data++; // \ is now a special character so it needs to be marked up using itself
349 else if (c=='\\' && *data == 'n')
350 { // and do new lines while we're at it.
354 else if (c=='\"'||c=='\0')
361 if (c >= '0' && c <= '9')
363 if (c == '0' && data[1] == 'x')
370 { //parse regular number
375 if ((c<'0'|| c>'9') && (c<'a'||c>'f') && (c<'A'||c>'F') && c != '.')
383 { //parse regular number
388 if ((c<'0'|| c>'9') && c != '.')
397 else if ((c>= 'a' && c <= 'z') || (c>= 'A' && c <= 'Z') || c == '_')
405 } while ((c>= 'a' && c <= 'z') || (c>= 'A' && c <= 'Z') || c == '_');
419 char *VARGS qcva (char *text, ...)
422 static char msg[2048];
424 va_start (argptr,text);
425 QC_vsnprintf (msg,sizeof(msg)-1, text,argptr);
434 char *QC_strupr (char *start)
446 char *QC_strlower (char *start)
460 =============================================================================
464 =============================================================================
471 For abnormal program terminations
474 void VARGS QCC_Error (int errortype, const char *error, ...)
476 extern int numsourcefiles;
480 va_start (argptr,error);
481 QC_vsnprintf (msg,sizeof(msg)-1, error,argptr);
484 printf ("\n************ ERROR ************\n%s\n", msg);
487 editbadfile(strings+s_file, pr_source_line);
492 longjmp(qcccompileerror, 1);
494 print ("Press any key\n");
505 Checks for the given parameter in the program's command line arguments
506 Returns the argument number (1 to argc-1) or 0 if not present
509 int QCC_CheckParm (char *check)
513 for (i = 1;i<myargc;i++)
515 if ( !QC_strcasecmp(check, myargv[i]) )
530 int SafeOpenWrite (char *filename)
536 handle = open(filename,O_WRONLY | O_CREAT | O_TRUNC | O_BINARY
540 QCC_Error ("Error opening %s: %s",filename,strerror(errno));
546 int SafeOpenRead (char *filename)
550 handle = open(filename,O_RDONLY | O_BINARY);
553 QCC_Error ("Error opening %s: %s",filename,strerror(errno));
559 void SafeRead (int handle, void *buffer, long count)
561 if (read (handle,buffer,count) != count)
562 QCC_Error ("File read failure");
566 void SafeWrite (int handle, void *buffer, long count)
568 if (write (handle,buffer,count) != count)
569 QCC_Error ("File write failure");
574 void *SafeMalloc (long size)
578 ptr = (void *)Hunk_Alloc (size);
581 QCC_Error ("Malloc failure for %lu bytes",size);
590 void DefaultExtension (char *path, char *extension)
594 // if path doesn't have a .EXT, append extension
595 // (extension should include the .)
597 src = path + strlen(path) - 1;
599 while (*src != PATHSEPERATOR && src != path)
602 return; // it has an extension
606 strcat (path, extension);
610 void DefaultPath (char *path, char *basepath)
614 if (path[0] == PATHSEPERATOR)
615 return; // absolute path location
617 strcpy (path,basepath);
622 void StripFilename (char *path)
626 length = strlen(path)-1;
627 while (length > 0 && path[length] != PATHSEPERATOR)
637 void ExtractFilePath (char *path, char *dest)
641 src = path + strlen(path) - 1;
644 // back up until a \ or the start
646 while (src != path && *(src-1) != PATHSEPERATOR)
649 memcpy (dest, path, src-path);
653 void ExtractFileBase (char *path, char *dest)
657 src = path + strlen(path) - 1;
660 // back up until a \ or the start
662 while (src != path && *(src-1) != PATHSEPERATOR)
665 while (*src && *src != '.')
672 void ExtractFileExtension (char *path, char *dest)
676 src = path + strlen(path) - 1;
679 // back up until a . or the start
681 while (src != path && *(src-1) != '.')
685 *dest = 0; // no extension
698 long ParseHex (char *hex)
709 if (*str >= '0' && *str <= '9')
711 else if (*str >= 'a' && *str <= 'f')
712 num += 10 + *str-'a';
713 else if (*str >= 'A' && *str <= 'F')
714 num += 10 + *str-'A';
716 QCC_Error (ERR_BADHEX, "Bad hex number: %s",hex);
724 long ParseNum (char *str)
727 return ParseHex (str+1);
728 if (str[0] == '0' && str[1] == 'x')
729 return ParseHex (str+2);
740 //buffer size and max size are different. buffer is bigger.
742 #define MAXQCCFILES 3
750 } qccfile[MAXQCCFILES];
751 int SafeOpenWrite (char *filename, int maxsize)
754 for (i = 0; i < MAXQCCFILES; i++)
756 if (!qccfile[i].buff)
758 strcpy(qccfile[i].name, filename);
759 qccfile[i].buffsize = maxsize;
760 qccfile[i].maxofs = 0;
762 // if (maxsize > 8192)
763 // qccfile[i].buffismalloc = 1;
765 // qccfile[i].buffismalloc = 0;
766 // if (qccfile[i].buffismalloc)
767 qccfile[i].buff = malloc(qccfile[i].buffsize);
769 // qccfile[i].buff = memalloc(qccfile[i].buffsize);
773 QCC_Error(ERR_TOOMANYOPENFILES, "Too many open files on file %s", filename);
777 void ResizeBuf(int hand, int newsize)
779 // int wasmal = qccfile[hand].buffismalloc;
782 if (qccfile[hand].buffsize >= newsize)
783 return; //already big enough
785 // if (newsize > 8192)
787 // qccfile[hand].buffismalloc = true;
788 nb = malloc(newsize);
792 // qccfile[hand].buffismalloc = false;
793 // nb = memalloc(newsize);
796 memcpy(nb, qccfile[hand].buff, qccfile[hand].maxofs);
798 free(qccfile[hand].buff);
800 // memfree(qccfile[hand].buff);
801 qccfile[hand].buff = nb;
802 qccfile[hand].buffsize = newsize;
804 void SafeWrite(int hand, void *buf, long count)
806 if (qccfile[hand].ofs +count >= qccfile[hand].buffsize)
807 ResizeBuf(hand, qccfile[hand].ofs + count+(64*1024));
809 memcpy(&qccfile[hand].buff[qccfile[hand].ofs], buf, count);
810 qccfile[hand].ofs+=count;
811 if (qccfile[hand].ofs > qccfile[hand].maxofs)
812 qccfile[hand].maxofs = qccfile[hand].ofs;
814 int SafeSeek(int hand, int ofs, int mode)
816 if (mode == SEEK_CUR)
817 return qccfile[hand].ofs;
820 ResizeBuf(hand, ofs+1024);
821 qccfile[hand].ofs = ofs;
822 if (qccfile[hand].ofs > qccfile[hand].maxofs)
823 qccfile[hand].maxofs = qccfile[hand].ofs;
827 void SafeClose(int hand)
829 externs->WriteFile(qccfile[hand].name, qccfile[hand].buff, qccfile[hand].maxofs);
830 // if (qccfile[hand].buffismalloc)
831 free(qccfile[hand].buff);
833 // memfree(qccfile[hand].buff);
834 qccfile[hand].buff = NULL;
837 qcc_cachedsourcefile_t *qcc_sourcefile;
838 long QCC_LoadFile (char *filename, void **bufferptr)
842 len = externs->FileSize(filename);
845 QCC_Error(ERR_COULDNTOPENFILE, "Couldn't open file %s", filename);
848 // Abort("failed to find file %s", filename);
850 mem = qccHunkAlloc(sizeof(qcc_cachedsourcefile_t) + len+2);
852 ((qcc_cachedsourcefile_t*)mem)->next = qcc_sourcefile;
853 qcc_sourcefile = (qcc_cachedsourcefile_t*)mem;
854 qcc_sourcefile->size = len;
855 mem += sizeof(qcc_cachedsourcefile_t);
856 strcpy(qcc_sourcefile->filename, filename);
857 qcc_sourcefile->file = mem;
858 qcc_sourcefile->type = FT_CODE;
860 externs->ReadFile(filename, mem, len+2);
867 void QCC_AddFile (char *filename)
871 len = externs->FileSize(filename);
873 Abort("failed to find file %s", filename);
874 mem = qccHunkAlloc(sizeof(qcc_cachedsourcefile_t) + len+1);
876 ((qcc_cachedsourcefile_t*)mem)->next = qcc_sourcefile;
877 qcc_sourcefile = (qcc_cachedsourcefile_t*)mem;
878 qcc_sourcefile->size = len;
879 mem += sizeof(qcc_cachedsourcefile_t);
880 strcpy(qcc_sourcefile->filename, filename);
881 qcc_sourcefile->file = mem;
882 qcc_sourcefile->type = FT_DATA;
884 externs->ReadFile(filename, mem, len+1);
887 void *FS_ReadToMem(char *filename, void *mem, int *len)
891 *len = externs->FileSize(filename);
892 mem = memalloc(*len);
894 return externs->ReadFile(filename, mem, *len);
897 void FS_CloseFromMem(void *mem)
905 void StripExtension (char *path)
909 length = strlen(path)-1;
910 while (length > 0 && path[length] != '.')
913 if (path[length] == '/')
914 return; // no extension