2004-08-25 03:42:49 +00:00
# include "qcc.h"
# include "gui.h"
2019-01-20 01:00:18 +00:00
# ifndef _WIN32
2019-01-15 14:12:49 +00:00
# include <unistd.h>
# endif
2019-04-19 23:55:47 +00:00
# if defined(_WIN32) || defined(__DJGPP__)
# include <malloc.h>
# else
# include <alloca.h>
# endif
2005-02-28 07:16:19 +00:00
//common gui things
2013-06-23 02:17:02 +00:00
pbool fl_nondfltopts ;
2005-02-28 07:16:19 +00:00
pbool fl_hexen2 ;
2015-04-14 12:24:05 +00:00
pbool fl_ftetarg ;
2005-02-28 07:16:19 +00:00
pbool fl_compileonstart ;
pbool fl_showall ;
2005-03-01 15:36:23 +00:00
pbool fl_log ;
2015-04-14 12:24:05 +00:00
pbool fl_extramargins ;
2017-06-21 01:24:25 +00:00
int fl_tabsize ;
2005-02-28 07:16:19 +00:00
char parameters [ 16384 ] ;
char progssrcname [ 256 ] ;
char progssrcdir [ 256 ] ;
2019-01-15 14:12:49 +00:00
char enginebinary [ MAX_OSPATH ] ;
char enginebasedir [ MAX_OSPATH ] ;
2014-12-23 15:26:42 +00:00
char enginecommandline [ 8192 ] ;
2005-02-28 07:16:19 +00:00
2019-01-20 01:00:18 +00:00
pbool qcc_vfiles_changed ;
vfile_t * qcc_vfiles ;
//for finding symbol keywords
extern QCC_def_t * sourcefilesdefs [ ] ;
extern int sourcefilesnumdefs ;
int Grep ( const char * filename , const char * string )
2013-08-11 17:18:44 +00:00
{
int foundcount = 0 ;
char * last , * found , * linestart ;
int line = 1 ;
2018-01-22 19:18:04 +00:00
size_t sz ;
2016-10-22 07:06:51 +00:00
char * raw , * buf ;
pbool dofree ;
int origfmt ;
2013-08-11 17:18:44 +00:00
if ( ! filename )
return foundcount ;
2018-01-22 19:18:04 +00:00
2018-04-20 19:09:14 +00:00
raw = GUIReadFile ( filename , NULL , NULL , & sz , false ) ;
2018-01-22 19:18:04 +00:00
if ( ! raw )
2013-08-11 17:18:44 +00:00
return foundcount ;
2018-01-22 19:18:04 +00:00
if ( raw [ sz ] ! = 0 )
return foundcount ; //error....
2016-10-22 07:06:51 +00:00
buf = QCC_SanitizeCharSet ( raw , & sz , & dofree , & origfmt ) ;
2015-12-12 19:25:15 +00:00
2013-08-11 17:18:44 +00:00
linestart = last = found = buf ;
2016-07-12 00:40:13 +00:00
while ( ( found = QC_strcasestr ( found , string ) ) )
2013-08-11 17:18:44 +00:00
{
while ( last < found )
{
if ( * last + + = = ' \n ' )
{
line + + ;
linestart = last ;
}
}
while ( * found & & * found ! = ' \n ' )
found + + ;
if ( * found )
* found + + = ' \0 ' ;
GUIprintf ( " %s:%i: %s \n " , filename , line , linestart ) ;
line + + ;
linestart = found ;
foundcount + + ;
}
2016-10-22 07:06:51 +00:00
if ( dofree )
free ( buf ) ;
free ( raw ) ;
2013-08-11 17:18:44 +00:00
return foundcount ;
}
2019-01-20 01:00:18 +00:00
void GoToDefinition ( const char * name )
2004-08-25 03:42:49 +00:00
{
2017-06-05 15:20:57 +00:00
# define MAXSOURCEFILESLIST 8
extern QCC_def_t * sourcefilesdefs [ MAXSOURCEFILESLIST ] ;
extern int sourcefilesnumdefs ;
int fno ;
QCC_def_t * def , * guess ;
2015-04-14 12:24:05 +00:00
QCC_function_t * fnc ;
2004-08-25 03:42:49 +00:00
2019-01-20 01:00:18 +00:00
const char * strip ; //trim whitespace (for convieniance).
2004-08-25 03:42:49 +00:00
while ( * name < = ' ' & & * name )
name + + ;
2019-01-20 01:00:18 +00:00
for ( strip = name + strlen ( name ) - 1 ; strip > name ; strip - - )
2004-08-25 03:42:49 +00:00
{
if ( * strip < = ' ' )
2019-01-20 01:00:18 +00:00
continue ;
2004-08-25 03:42:49 +00:00
else //got some part of a word
break ;
}
2019-01-20 01:00:18 +00:00
if ( * strip < = ' ' )
{
char * t = alloca ( strip - name + 1 ) ;
memcpy ( t , name , strip - t ) ;
t [ strip - t ] = 0 ;
name = t ;
}
2004-08-25 03:42:49 +00:00
if ( ! globalstable . numbuckets )
{
2005-02-28 07:16:19 +00:00
GUI_DialogPrint ( " Not found " , " You need to compile first. " ) ;
2004-08-25 03:42:49 +00:00
return ;
}
2008-10-05 02:55:01 +00:00
def = QCC_PR_GetDef ( NULL , name , NULL , false , 0 , false ) ;
2004-08-25 03:42:49 +00:00
2017-06-05 15:20:57 +00:00
//no exact match, see if we can get a case-insensitive match
if ( ! def & & * name )
{
for ( fno = 0 ; fno < sourcefilesnumdefs ; fno + + )
{
for ( def = sourcefilesdefs [ fno ] ; def ; def = def - > next )
{
if ( def - > scope )
continue ; //ignore locals, because we don't know where we are, and they're probably irrelevent.
if ( ! QC_strcasecmp ( def - > name , name ) )
{
fno = sourcefilesnumdefs ;
break ;
}
}
}
}
//no exact match, see if we can get a partial
if ( ! def & & * name )
{
int prefixlen = strlen ( name ) ;
for ( fno = 0 ; fno < sourcefilesnumdefs ; fno + + )
{
for ( guess = sourcefilesdefs [ fno ] ; guess ; guess = guess - > next )
{
if ( guess - > scope )
continue ; //ignore locals, because we don't know where we are, and they're probably irrelevent.
//make sure it has the right prefix
if ( ! QC_strncasecmp ( guess - > name , name , prefixlen ) )
{
if ( guess - > type - > type = = ev_function & & guess - > constant & & ! guess - > arraysize )
{ //if we found a function, use that one above all others.
def = guess ;
fno = sourcefilesnumdefs ;
break ;
}
else if ( ! def )
def = guess ;
}
}
}
}
2004-08-25 03:42:49 +00:00
if ( def )
{
2015-01-07 13:34:05 +00:00
//with functions, the def is the prototype.
//we want the body, so zoom to the first statement of the function instead
2015-04-27 06:19:33 +00:00
if ( def - > type - > type = = ev_function & & def - > constant & & ! def - > arraysize )
2004-08-25 03:42:49 +00:00
{
2017-06-05 15:20:57 +00:00
int fnum = def - > symboldata [ 0 ] . function ;
2015-06-18 22:11:30 +00:00
if ( fnum > 0 & & fnum < numfunctions )
2004-08-25 03:42:49 +00:00
{
2015-06-18 22:11:30 +00:00
fnc = & functions [ fnum ] ;
2016-09-08 19:04:35 +00:00
if ( fnc - > code > = 0 & & fnc - > filen )
2015-06-18 22:11:30 +00:00
{
2017-06-05 15:20:57 +00:00
EditFile ( fnc - > filen , fnc - > line , false ) ;
2015-06-18 22:11:30 +00:00
return ;
}
2004-08-25 03:42:49 +00:00
}
}
2016-09-08 19:04:35 +00:00
if ( ! def - > filen )
2016-07-12 00:40:13 +00:00
{
char msgbuffer [ 2048 ] ;
QC_snprintfz ( msgbuffer , sizeof ( msgbuffer ) , " Global definition of \" %s \" was not specified. " , name ) ;
GUI_DialogPrint ( " Not found " , msgbuffer ) ;
}
2008-11-09 22:29:28 +00:00
else
2016-09-08 19:04:35 +00:00
EditFile ( def - > filen , def - > s_line - 1 , false ) ;
2004-08-25 03:42:49 +00:00
}
else
2016-07-12 00:40:13 +00:00
{
char msgbuffer [ 2048 ] ;
QC_snprintfz ( msgbuffer , sizeof ( msgbuffer ) , " Global instance of \" %s \" was not found. " , name ) ;
GUI_DialogPrint ( " Not found " , msgbuffer ) ;
}
2005-02-28 07:16:19 +00:00
}
2020-03-14 17:38:55 +00:00
pbool GenAutoCompleteList ( char * prefix , char * buffer , int buffersize )
{
QCC_def_t * def ;
int prefixlen = strlen ( prefix ) ;
int usedbuffer = 0 ;
int l ;
int fno ;
for ( fno = 0 ; fno < sourcefilesnumdefs ; fno + + )
{
for ( def = sourcefilesdefs [ fno ] ; def ; def = def - > next )
{
if ( def - > scope )
continue ; //ignore locals, because we don't know where we are, and they're probably irrelevent.
//make sure it has the right prefix
if ( ! strncmp ( def - > name , prefix , prefixlen ) )
//but ignore it if its one of those special things that you're not meant to know about.
if ( strcmp ( def - > name , " IMMEDIATE " ) & & ! strchr ( def - > name , ' : ' ) & & ! strchr ( def - > name , ' . ' ) & & ! strchr ( def - > name , ' * ' ) & & ! strchr ( def - > name , ' [ ' ) )
{
l = strlen ( def - > name ) ;
if ( l & & usedbuffer + 2 + l < buffersize )
{
if ( usedbuffer )
buffer [ usedbuffer + + ] = ' ' ;
memcpy ( buffer + usedbuffer , def - > name , l ) ;
usedbuffer + = l ;
}
}
}
}
buffer [ usedbuffer ] = 0 ;
return usedbuffer > 0 ;
}
2015-04-14 12:24:05 +00:00
static void GUI_WriteConfigLine ( FILE * file , char * part1 , char * part2 , char * part3 , char * desc )
{
int align = 0 ;
if ( part1 )
{
if ( strchr ( part1 , ' ' ) )
align + = fprintf ( file , " \" %s \" " , part1 ) ;
else
align + = fprintf ( file , " %s " , part1 ) ;
for ( ; align < 14 ; align + + )
fputc ( ' ' , file ) ;
}
if ( part2 )
{
if ( strchr ( part2 , ' ' ) )
align + = fprintf ( file , " \" %s \" " , part2 ) ;
else
align + = fprintf ( file , " %s " , part2 ) ;
for ( ; align < 28 ; align + + )
fputc ( ' ' , file ) ;
}
if ( part3 )
{
if ( strchr ( part3 , ' ' ) )
align + = fprintf ( file , " \" %s \" " , part3 ) ;
else
align + = fprintf ( file , " %s " , part3 ) ;
for ( ; align < 40 ; align + + )
fputc ( ' ' , file ) ;
}
if ( desc )
{
if ( align > 40 )
{
fputc ( ' \n ' , file ) ;
align = 0 ;
}
for ( ; align < 40 ; align + + )
fputc ( ' ' , file ) ;
fputs ( " # " , file ) ;
align - = 40 ;
if ( align < 0 )
align = 0 ;
while ( * desc )
{
if ( * desc = = ' \n ' | | ( * desc = = ' ' & & align > 60 ) )
{
fputs ( " \n " , file ) ;
for ( align = 0 ; align < 40 ; align + + )
fputc ( ' ' , file ) ;
fputs ( " # " , file ) ;
align = 0 ;
}
else
{
fputc ( * desc , file ) ;
align + + ;
}
desc + + ;
}
}
fputs ( " \n " , file ) ;
}
2017-06-21 01:24:25 +00:00
static void GUI_WriteConfigInt ( FILE * file , char * part1 , int part2 , char * desc )
{
char buf [ 64 ] ;
QC_snprintfz ( buf , sizeof ( buf ) , " %i " , part2 ) ;
GUI_WriteConfigLine ( file , part1 , buf , NULL , desc ) ;
}
2015-04-14 12:24:05 +00:00
void GUI_SaveConfig ( void )
{
FILE * file = fopen ( " fteqcc.ini " , " wt " ) ;
int p ;
if ( ! file )
return ;
for ( p = 0 ; optimisations [ p ] . enabled ; p + + )
{
if ( ( ! ( optimisations [ p ] . flags & FLAG_SETINGUI ) ) = = ( ! ( optimisations [ p ] . flags & FLAG_ASDEFAULT ) ) )
GUI_WriteConfigLine ( file , " optimisation " , optimisations [ p ] . abbrev , " default " , optimisations [ p ] . description ) ;
else
GUI_WriteConfigLine ( file , " optimisation " , optimisations [ p ] . abbrev , ( optimisations [ p ] . flags & FLAG_SETINGUI ) ? " on " : " off " , optimisations [ p ] . description ) ;
}
for ( p = 0 ; compiler_flag [ p ] . enabled ; p + + )
{
if ( ! strncmp ( compiler_flag [ p ] . fullname , " Keyword: " , 9 ) )
GUI_WriteConfigLine ( file , " keyword " , compiler_flag [ p ] . abbrev , ( compiler_flag [ p ] . flags & FLAG_SETINGUI ) ? " true " : " false " , compiler_flag [ p ] . description ) ;
else
GUI_WriteConfigLine ( file , " flag " , compiler_flag [ p ] . abbrev , ( compiler_flag [ p ] . flags & FLAG_SETINGUI ) ? " true " : " false " , compiler_flag [ p ] . description ) ;
}
2005-02-28 07:16:19 +00:00
2015-04-14 12:24:05 +00:00
GUI_WriteConfigLine ( file , " showall " , fl_showall ? " on " : " off " , NULL , " Show all keyword options in the gui " ) ;
GUI_WriteConfigLine ( file , " compileonstart " , fl_compileonstart ? " on " : " off " , NULL , " Recompile on GUI startup " ) ;
GUI_WriteConfigLine ( file , " log " , fl_log ? " on " : " off " , NULL , " Write out a compile log " ) ;
GUI_WriteConfigLine ( file , " enginebinary " , enginebinary , NULL , " Location of the engine binary to run. Change this to something else to run a different engine, but not all support debugging. " ) ;
GUI_WriteConfigLine ( file , " basedir " , enginebasedir , NULL , " The base directory of the game that contains your sub directory " ) ;
GUI_WriteConfigLine ( file , " engineargs " , enginecommandline , NULL , " The engine commandline to use when debugging. You'll likely want to ensure this contains -window as well as the appropriate -game argument. " ) ;
GUI_WriteConfigLine ( file , " srcfile " , progssrcname , NULL , " The progs.src file to load to find ordering of other qc files. " ) ;
GUI_WriteConfigLine ( file , " src " , progssrcdir , NULL , " Additional subdir to read qc files from. Typically blank (ie: the working directory). " ) ;
2017-06-21 01:24:25 +00:00
GUI_WriteConfigInt ( file , " tabsize " , fl_tabsize , " Specifies the size of tabs in scintilla windows. " ) ;
2015-04-14 12:24:05 +00:00
GUI_WriteConfigLine ( file , " extramargins " , fl_extramargins ? " on " : " off " , NULL , " Enables line number and folding margins. " ) ;
GUI_WriteConfigLine ( file , " hexen2 " , fl_hexen2 ? " on " : " off " , NULL , " Enable the extra tweaks needed for compatibility with hexen2 engines. " ) ;
GUI_WriteConfigLine ( file , " extendedopcodes " , fl_ftetarg ? " on " : " off " , NULL , " Utilise an extended instruction set, providing support for pointers and faster arrays and other speedups. " ) ;
GUI_WriteConfigLine ( file , " parameters " , parameters , NULL , " Other additional parameters that are not supported by the gui. Likely including -DFOO " ) ;
fclose ( file ) ;
}
//grabs a token. modifies original string.
static char * GUI_ParseInPlace ( char * * state )
{
char * str = * state , * end ;
while ( * str = = ' ' | | * str = = ' \t ' )
str + + ;
if ( * str = = ' \" ' )
{
char * fmt ;
str + + ;
for ( end = str , fmt = str ; * end ; )
{
if ( * end = = ' \" ' )
2020-08-03 10:34:44 +00:00
{
end + + ;
2015-04-14 12:24:05 +00:00
break ;
2020-08-03 10:34:44 +00:00
}
2015-04-14 12:24:05 +00:00
else if ( * end = = ' \' ' & & end [ 1 ] = = ' \\ ' )
* fmt = ' \\ ' ;
else if ( * end = = ' \' ' & & end [ 1 ] = = ' \" ' )
* fmt = ' \" ' ;
else if ( * end = = ' \' ' & & end [ 1 ] = = ' \n ' )
* fmt = ' \n ' ;
else if ( * end = = ' \' ' & & end [ 1 ] = = ' \r ' )
* fmt = ' \r ' ;
else if ( * end = = ' \' ' & & end [ 1 ] = = ' \t ' )
* fmt = ' \t ' ;
else
{
* fmt + + = * end + + ;
continue ;
}
fmt + = 1 ;
end + = 2 ;
}
}
else
2020-08-03 10:34:44 +00:00
{
for ( end = str ; * end ; end + + )
{
if ( * end = = ' # ' )
{
while ( * end & & * end ! = ' \n ' )
end + + ;
break ;
}
if ( * end = = ' ' | | * end = = ' \t ' | | * end = = ' \n ' )
break ;
}
}
2015-04-14 12:24:05 +00:00
* end = 0 ;
2020-08-03 10:34:44 +00:00
* state = end ;
2015-04-14 12:24:05 +00:00
return str ;
}
2017-06-21 01:24:25 +00:00
static int GUI_ParseIntInPlace ( char * * state , int defaultval )
{
char * token = GUI_ParseInPlace ( state ) ;
if ( ! stricmp ( token , " default " ) )
return defaultval ;
else if ( ! stricmp ( token , " on " ) | | ! stricmp ( token , " true " ) | | ! stricmp ( token , " yes " ) )
return 1 ;
else if ( ! stricmp ( token , " off " ) | | ! stricmp ( token , " false " ) | | ! stricmp ( token , " no " ) )
return 0 ;
else
return atoi ( token ) ;
}
2015-04-14 12:24:05 +00:00
static int GUI_ParseBooleanInPlace ( char * * state , int defaultval )
{
char * token = GUI_ParseInPlace ( state ) ;
if ( ! stricmp ( token , " default " ) )
return defaultval ;
else if ( ! stricmp ( token , " on " ) | | ! stricmp ( token , " true " ) | | ! stricmp ( token , " yes " ) )
return 1 ;
else if ( ! stricmp ( token , " off " ) | | ! stricmp ( token , " false " ) | | ! stricmp ( token , " no " ) )
return 0 ;
else
return ! ! atoi ( token ) ;
}
void GUI_LoadConfig ( void )
{
char buf [ 2048 ] ;
char * token , * str ;
FILE * file = fopen ( " fteqcc.ini " , " rb " ) ;
int p ;
2017-06-21 01:24:25 +00:00
//initialise gui-only stuff.
fl_compileonstart = false ;
fl_extramargins = false ;
fl_tabsize = 8 ;
2015-04-14 12:24:05 +00:00
if ( ! file )
return ;
fl_nondfltopts = false ;
while ( fgets ( buf , sizeof ( buf ) , file ) )
{
str = buf ;
token = GUI_ParseInPlace ( & str ) ;
if ( ! stricmp ( token , " optimisation " ) | | ! stricmp ( token , " opt " ) )
{
char * item = GUI_ParseInPlace ( & str ) ;
int value = GUI_ParseBooleanInPlace ( & str , - 1 ) ;
for ( p = 0 ; optimisations [ p ] . enabled ; p + + )
if ( ! stricmp ( item , optimisations [ p ] . abbrev ) )
{
if ( value = = - 1 )
value = ! ! ( optimisations [ p ] . flags & FLAG_ASDEFAULT ) ;
else
fl_nondfltopts = true ;
if ( value )
optimisations [ p ] . flags | = FLAG_SETINGUI ;
else
optimisations [ p ] . flags & = ~ FLAG_SETINGUI ;
break ;
}
//don't worry if its not known
}
else if ( ! stricmp ( token , " flag " ) | | ! stricmp ( token , " fl " ) | | ! stricmp ( token , " keyword " ) )
{
char * item = GUI_ParseInPlace ( & str ) ;
int value = GUI_ParseBooleanInPlace ( & str , - 1 ) ;
for ( p = 0 ; compiler_flag [ p ] . enabled ; p + + )
if ( ! stricmp ( item , compiler_flag [ p ] . abbrev ) )
{
if ( value = = - 1 )
value = ! ! ( compiler_flag [ p ] . flags & FLAG_ASDEFAULT ) ;
if ( value )
compiler_flag [ p ] . flags | = FLAG_SETINGUI ;
else
compiler_flag [ p ] . flags & = ~ FLAG_SETINGUI ;
break ;
}
//don't worry if its not known
}
else if ( ! stricmp ( token , " enginebinary " ) )
QC_strlcpy ( enginebinary , GUI_ParseInPlace ( & str ) , sizeof ( enginebinary ) ) ;
else if ( ! stricmp ( token , " basedir " ) )
QC_strlcpy ( enginebasedir , GUI_ParseInPlace ( & str ) , sizeof ( enginebasedir ) ) ;
else if ( ! stricmp ( token , " engineargs " ) )
QC_strlcpy ( enginecommandline , GUI_ParseInPlace ( & str ) , sizeof ( enginecommandline ) ) ;
2016-01-18 05:22:07 +00:00
// else if (!stricmp(token, "srcfile"))
// QC_strlcpy(progssrcname, GUI_ParseInPlace(&str), sizeof(progssrcname));
// else if (!stricmp(token, "src"))
// QC_strlcpy(progssrcdir, GUI_ParseInPlace(&str), sizeof(progssrcdir));
2015-04-14 12:24:05 +00:00
else if ( ! stricmp ( token , " parameters " ) )
QC_strlcpy ( parameters , GUI_ParseInPlace ( & str ) , sizeof ( parameters ) ) ;
else if ( ! stricmp ( token , " log " ) )
fl_log = GUI_ParseBooleanInPlace ( & str , false ) ;
else if ( ! stricmp ( token , " compileonstart " ) )
fl_compileonstart = GUI_ParseBooleanInPlace ( & str , false ) ;
else if ( ! stricmp ( token , " showall " ) )
fl_showall = GUI_ParseBooleanInPlace ( & str , false ) ;
2017-06-21 01:24:25 +00:00
else if ( ! stricmp ( token , " tabsize " ) )
fl_tabsize = GUI_ParseIntInPlace ( & str , false ) ;
2015-04-14 12:24:05 +00:00
else if ( ! stricmp ( token , " extramargins " ) )
fl_extramargins = GUI_ParseBooleanInPlace ( & str , false ) ;
else if ( ! stricmp ( token , " hexen2 " ) )
fl_hexen2 = GUI_ParseBooleanInPlace ( & str , false ) ;
else if ( ! stricmp ( token , " extendedopcodes " ) )
fl_ftetarg = GUI_ParseBooleanInPlace ( & str , false ) ;
else if ( * token )
{
2020-08-03 10:34:44 +00:00
puts ( " Unknown setting: \" " ) ; puts ( token ) ; puts ( " \" \n " ) ;
2015-04-14 12:24:05 +00:00
}
}
fclose ( file ) ;
}
2005-02-28 07:16:19 +00:00
//this function takes the windows specified commandline and strips out all the options menu items.
2019-01-20 01:00:18 +00:00
int GUI_ParseCommandLine ( const char * args , pbool keepsrcanddir )
2005-02-28 07:16:19 +00:00
{
int paramlen = 0 ;
int l , p ;
2019-01-20 01:00:18 +00:00
const char * next ;
2018-03-04 14:41:16 +00:00
int mode = 0 ;
2020-07-01 05:32:21 +00:00
extern int qccpersisthunk ;
2015-04-14 12:24:05 +00:00
2017-07-12 08:15:27 +00:00
if ( ! * args )
{
int len ;
FILE * f ;
char * s ;
f = fopen ( " fteqcc.arg " , " rb " ) ;
if ( f )
{
fseek ( f , 0 , SEEK_END ) ;
len = ftell ( f ) ;
fseek ( f , 0 , SEEK_SET ) ;
2019-01-15 14:12:49 +00:00
args = alloca ( len + 1 ) ;
2019-01-20 01:00:18 +00:00
fread ( ( char * ) args , 1 , len , f ) ;
( ( char * ) args ) [ len ] = ' \0 ' ;
2017-07-12 08:15:27 +00:00
fclose ( f ) ;
while ( ( s = strchr ( args , ' \r ' ) ) )
* s = ' ' ;
while ( ( s = strchr ( args , ' \n ' ) ) )
* s = ' ' ;
}
}
2015-04-14 12:24:05 +00:00
//find the first argument
while ( * args = = ' ' | | * args = = ' \t ' )
args + + ;
for ( next = args ; * next & & * next ! = ' ' & & * next ! = ' \t ' ; next + + )
;
2017-07-12 08:15:27 +00:00
2015-04-14 12:24:05 +00:00
if ( * args ! = ' - ' )
2005-02-28 07:16:19 +00:00
{
2015-04-14 12:24:05 +00:00
pbool qt = * args = = ' \" ' ;
l = 0 ;
if ( qt )
2005-02-28 07:16:19 +00:00
args + + ;
2015-06-16 23:53:58 +00:00
while ( ( * args ! = ' ' | | qt ) & & * args )
2015-04-14 12:24:05 +00:00
{
if ( qt & & * args = = ' \" ' )
{
args + + ;
break ;
}
2018-04-16 21:46:10 +00:00
if ( ! keepsrcanddir )
progssrcname [ l + + ] = * args ;
args + + ;
2015-04-14 12:24:05 +00:00
}
2018-04-16 21:46:10 +00:00
if ( ! keepsrcanddir )
progssrcname [ l ] = 0 ;
2005-02-28 07:16:19 +00:00
2015-04-14 12:24:05 +00:00
next = args ;
2018-04-16 21:46:10 +00:00
if ( ! keepsrcanddir )
2015-04-14 12:24:05 +00:00
{
2018-04-16 21:46:10 +00:00
args = strrchr ( progssrcname , ' \\ ' ) ;
while ( args & & strchr ( args , ' / ' ) )
args = strchr ( args , ' / ' ) ;
if ( args )
{
memcpy ( progssrcdir , progssrcname , args - progssrcname ) ;
progssrcdir [ args - progssrcname ] = 0 ;
args + + ;
memmove ( progssrcname , args , strlen ( args ) + 1 ) ;
2015-04-14 12:24:05 +00:00
2019-01-15 14:12:49 +00:00
# ifdef _WIN32
2018-04-16 21:46:10 +00:00
SetCurrentDirectoryA ( progssrcdir ) ;
2019-01-15 14:12:49 +00:00
# else
chdir ( progssrcdir ) ;
# endif
2018-04-16 21:46:10 +00:00
* progssrcdir = 0 ;
}
2015-04-14 12:24:05 +00:00
}
args = next ;
}
GUI_LoadConfig ( ) ;
2016-09-08 19:04:35 +00:00
paramlen = strlen ( parameters ) ;
if ( paramlen )
parameters [ paramlen + + ] = ' ' ;
2015-04-14 12:24:05 +00:00
while ( * args )
{
while ( * args = = ' ' | | * args = = ' \t ' )
args + + ;
for ( next = args ; * next & & * next ! = ' ' & & * next ! = ' \t ' ; next + + )
2005-02-28 07:16:19 +00:00
;
strncpy ( parameters + paramlen , args , next - args ) ;
parameters [ paramlen + next - args ] = ' \0 ' ;
l = strlen ( parameters + paramlen ) + 1 ;
2018-03-04 14:41:16 +00:00
if ( ! strnicmp ( parameters + paramlen , " -stdout " , 7 ) | | ! strnicmp ( parameters + paramlen , " --version " , 9 ) )
{
mode = 1 ;
}
/*else if (!strnicmp(parameters+paramlen, "-zippatch", 9))
{
mode = 2 ;
} */
else if ( ! strnicmp ( parameters + paramlen , " -O " , 2 ) | | ! strnicmp ( parameters + paramlen , " /O " , 2 ) )
2005-02-28 07:16:19 +00:00
{ //strip out all -O
2013-06-23 02:17:02 +00:00
fl_nondfltopts = true ;
2005-02-28 07:16:19 +00:00
if ( parameters [ paramlen + 2 ] )
{
if ( parameters [ paramlen + 2 ] > = ' 0 ' & & parameters [ paramlen + 2 ] < = ' 3 ' )
{
p = parameters [ paramlen + 2 ] - ' 0 ' ;
for ( l = 0 ; optimisations [ l ] . enabled ; l + + )
{
if ( optimisations [ l ] . optimisationlevel < = p )
optimisations [ l ] . flags | = FLAG_SETINGUI ;
else
optimisations [ l ] . flags & = ~ FLAG_SETINGUI ;
}
}
else if ( ! strncmp ( parameters + paramlen + 2 , " no- " , 3 ) )
{
if ( parameters [ paramlen + 5 ] )
{
for ( p = 0 ; optimisations [ p ] . enabled ; p + + )
if ( ( * optimisations [ p ] . abbrev & & ! strcmp ( parameters + paramlen + 5 , optimisations [ p ] . abbrev ) ) | | ! strcmp ( parameters + paramlen + 5 , optimisations [ p ] . fullname ) )
{
optimisations [ p ] . flags & = ~ FLAG_SETINGUI ;
break ;
}
if ( ! optimisations [ p ] . enabled )
{
parameters [ paramlen + next - args ] = ' ' ;
paramlen + = l ;
}
}
}
else
{
for ( p = 0 ; optimisations [ p ] . enabled ; p + + )
if ( ( * optimisations [ p ] . abbrev & & ! strcmp ( parameters + paramlen + 2 , optimisations [ p ] . abbrev ) ) | | ! strcmp ( parameters + paramlen + 2 , optimisations [ p ] . fullname ) )
{
optimisations [ p ] . flags | = FLAG_SETINGUI ;
break ;
}
if ( ! optimisations [ p ] . enabled )
{
parameters [ paramlen + next - args ] = ' ' ;
paramlen + = l ;
}
}
}
}
2014-03-01 11:38:53 +00:00
else if ( ! strnicmp ( parameters + paramlen , " -F " , 2 ) | | ! strnicmp ( parameters + paramlen , " /F " , 2 ) | | ! strnicmp ( parameters + paramlen , " -K " , 2 ) | | ! strnicmp ( parameters + paramlen , " /K " , 2 ) )
{
if ( parameters [ paramlen + 2 ] )
{
if ( ! strncmp ( parameters + paramlen + 2 , " no- " , 3 ) )
{
if ( parameters [ paramlen + 5 ] )
{
for ( p = 0 ; compiler_flag [ p ] . enabled ; p + + )
if ( ( * compiler_flag [ p ] . abbrev & & ! strcmp ( parameters + paramlen + 5 , compiler_flag [ p ] . abbrev ) ) | | ! strcmp ( parameters + paramlen + 5 , compiler_flag [ p ] . fullname ) )
{
compiler_flag [ p ] . flags & = ~ FLAG_SETINGUI ;
break ;
}
if ( ! compiler_flag [ p ] . enabled )
{
parameters [ paramlen + next - args ] = ' ' ;
paramlen + = l ;
}
}
}
else
{
for ( p = 0 ; compiler_flag [ p ] . enabled ; p + + )
if ( ( * compiler_flag [ p ] . abbrev & & ! strcmp ( parameters + paramlen + 2 , compiler_flag [ p ] . abbrev ) ) | | ! strcmp ( parameters + paramlen + 2 , compiler_flag [ p ] . fullname ) )
{
compiler_flag [ p ] . flags | = FLAG_SETINGUI ;
break ;
}
if ( ! compiler_flag [ p ] . enabled )
{
parameters [ paramlen + next - args ] = ' ' ;
paramlen + = l ;
}
}
}
}
2005-02-28 07:16:19 +00:00
/*
else if ( ! strnicmp ( parameters + paramlen , " -Fno-kce " , 8 ) | | ! strnicmp ( parameters + paramlen , " /Fno-kce " , 8 ) ) //keywords stuph
{
fl_nokeywords_coexist = true ;
}
else if ( ! strnicmp ( parameters + paramlen , " -Fkce " , 5 ) | | ! strnicmp ( parameters + paramlen , " /Fkce " , 5 ) )
{
fl_nokeywords_coexist = false ;
}
else if ( ! strnicmp ( parameters + paramlen , " -Facc " , 5 ) | | ! strnicmp ( parameters + paramlen , " /Facc " , 5 ) )
{
fl_acc = true ;
}
else if ( ! strnicmp ( parameters + paramlen , " -autoproto " , 10 ) | | ! strnicmp ( parameters + paramlen , " /autoproto " , 10 ) )
{
fl_autoprototype = true ;
}
*/
else if ( ! strnicmp ( parameters + paramlen , " -showall " , 8 ) | | ! strnicmp ( parameters + paramlen , " /showall " , 8 ) )
{
fl_showall = true ;
}
else if ( ! strnicmp ( parameters + paramlen , " -ac " , 3 ) | | ! strnicmp ( parameters + paramlen , " /ac " , 3 ) )
{
fl_compileonstart = true ;
}
2005-03-01 15:36:23 +00:00
else if ( ! strnicmp ( parameters + paramlen , " -log " , 4 ) | | ! strnicmp ( parameters + paramlen , " /log " , 4 ) )
{
fl_log = true ;
}
2020-05-29 10:27:43 +00:00
else if ( ! strnicmp ( parameters + paramlen , " -nolog " , 4 ) | | ! strnicmp ( parameters + paramlen , " /nolog " , 4 ) )
{
fl_log = false ;
}
2014-12-23 15:26:42 +00:00
else if ( ! strnicmp ( parameters + paramlen , " -engine " , 7 ) | | ! strnicmp ( parameters + paramlen , " /engine " , 7 ) )
{
while ( * next = = ' ' )
next + + ;
l = 0 ;
while ( * next ! = ' ' & & * next )
enginebinary [ l + + ] = * next + + ;
enginebinary [ l ] = 0 ;
}
else if ( ! strnicmp ( parameters + paramlen , " -basedir " , 8 ) | | ! strnicmp ( parameters + paramlen , " /basedir " , 8 ) )
{
while ( * next = = ' ' )
next + + ;
l = 0 ;
while ( * next ! = ' ' & & * next )
enginebasedir [ l + + ] = * next + + ;
enginebasedir [ l ] = 0 ;
}
//strcpy(enginecommandline, "-window +map start -nohome");
2006-01-02 23:01:54 +00:00
else if ( ! strnicmp ( parameters + paramlen , " -srcfile " , 8 ) | | ! strnicmp ( parameters + paramlen , " /srcfile " , 8 ) )
{
while ( * next = = ' ' )
next + + ;
2018-04-16 21:46:10 +00:00
if ( keepsrcanddir )
{ //ignore it
while ( * next ! = ' ' & & * next )
next + + ;
}
else
{
l = 0 ;
while ( * next ! = ' ' & & * next )
progssrcname [ l + + ] = * next + + ;
progssrcname [ l ] = 0 ;
}
2006-01-02 23:01:54 +00:00
}
2014-12-23 15:26:42 +00:00
else if ( ! strnicmp ( parameters + paramlen , " -src " , 5 ) | | ! strnicmp ( parameters + paramlen , " /src " , 5 ) )
{
while ( * next = = ' ' )
next + + ;
2018-04-16 21:46:10 +00:00
if ( keepsrcanddir )
{ //ignore it
while ( * next ! = ' ' & & * next )
next + + ;
}
else
{
l = 0 ;
while ( * next ! = ' ' & & * next )
progssrcdir [ l + + ] = * next + + ;
progssrcdir [ l ] = 0 ;
}
2014-12-23 15:26:42 +00:00
}
2005-02-28 07:16:19 +00:00
else if ( ! strnicmp ( parameters + paramlen , " -T " , 2 ) | | ! strnicmp ( parameters + paramlen , " /T " , 2 ) ) //the target
{
if ( ! strnicmp ( parameters + paramlen + 2 , " h2 " , 2 ) )
{
fl_hexen2 = true ;
}
else
{
fl_hexen2 = false ;
parameters [ paramlen + next - args ] = ' ' ;
paramlen + = l ;
}
}
2015-04-14 12:24:05 +00:00
/*
2014-12-31 07:43:04 +00:00
else if ( isfirst & & * args ! = ' - ' & & * args ! = ' / ' )
{
2015-02-02 08:01:53 +00:00
pbool qt = * args = = ' \" ' ;
2014-12-31 07:43:04 +00:00
l = 0 ;
2015-02-02 08:01:53 +00:00
if ( qt )
args + + ;
2014-12-31 07:43:04 +00:00
while ( * args ! = ' ' & & * args )
2015-02-02 08:01:53 +00:00
{
if ( qt & & * args = = ' \" ' )
{
args + + ;
break ;
}
2014-12-31 07:43:04 +00:00
progssrcname [ l + + ] = * args + + ;
2015-02-02 08:01:53 +00:00
}
2014-12-31 07:43:04 +00:00
progssrcname [ l ] = 0 ;
args = strrchr ( progssrcname , ' \\ ' ) ;
while ( args & & strchr ( args , ' / ' ) )
args = strchr ( args , ' / ' ) ;
if ( args )
{
memcpy ( progssrcdir , progssrcname , args - progssrcname ) ;
progssrcdir [ args - progssrcname ] = 0 ;
args + + ;
memmove ( progssrcname , args , strlen ( args ) + 1 ) ;
SetCurrentDirectoryA ( progssrcdir ) ;
* progssrcdir = 0 ;
}
}
2015-04-14 12:24:05 +00:00
*/
2005-02-28 07:16:19 +00:00
else
{
parameters [ paramlen + next - args ] = ' ' ;
paramlen + = l ;
}
args = next ;
}
if ( paramlen )
parameters [ paramlen - 1 ] = ' \0 ' ;
else
* parameters = ' \0 ' ;
2020-07-01 05:32:21 +00:00
qccpersisthunk = ( mode ! = 1 ) ;
2018-03-04 14:41:16 +00:00
return mode ;
2005-02-28 07:16:19 +00:00
}
void GUI_SetDefaultOpts ( void )
{
int i ;
for ( i = 0 ; compiler_flag [ i ] . enabled ; i + + ) //enabled is a pointer
{
if ( compiler_flag [ i ] . flags & FLAG_ASDEFAULT )
compiler_flag [ i ] . flags | = FLAG_SETINGUI ;
else
compiler_flag [ i ] . flags & = ~ FLAG_SETINGUI ;
}
for ( i = 0 ; optimisations [ i ] . enabled ; i + + ) //enabled is a pointer
{
if ( optimisations [ i ] . flags & FLAG_ASDEFAULT )
optimisations [ i ] . flags | = FLAG_SETINGUI ;
else
optimisations [ i ] . flags & = ~ FLAG_SETINGUI ;
}
}
void GUI_RevealOptions ( void )
{
int i ;
for ( i = 0 ; compiler_flag [ i ] . enabled ; i + + ) //enabled is a pointer
{
if ( fl_showall & & compiler_flag [ i ] . flags & FLAG_HIDDENINGUI )
compiler_flag [ i ] . flags & = ~ FLAG_HIDDENINGUI ;
}
for ( i = 0 ; optimisations [ i ] . enabled ; i + + ) //enabled is a pointer
{
if ( fl_showall & & optimisations [ i ] . flags & FLAG_HIDDENINGUI )
optimisations [ i ] . flags & = ~ FLAG_HIDDENINGUI ;
if ( optimisations [ i ] . flags & FLAG_HIDDENINGUI ) //hidden optimisations are disabled as default
optimisations [ i ] . optimisationlevel = 4 ;
}
}
2019-01-20 01:00:18 +00:00
int GUI_BuildParms ( const char * args , const char * * argv , pbool quick ) //, char *forceoutputfile)
2005-02-28 07:16:19 +00:00
{
static char param [ 2048 ] ;
int paramlen = 0 ;
int argc ;
2019-01-20 01:00:18 +00:00
const char * next ;
2005-02-28 07:16:19 +00:00
int i ;
2015-04-14 12:24:05 +00:00
int targ ;
char * targs [ ] = { " " , " -Th2 " , " -Tfte " , " -Tfteh2 " } ;
2005-02-28 07:16:19 +00:00
argc = 1 ;
argv [ 0 ] = " fteqcc " ;
2015-01-12 12:28:13 +00:00
if ( quick )
{
strcpy ( param + paramlen , " -Tparse " ) ;
argv [ argc + + ] = param + paramlen ;
paramlen + = strlen ( param + paramlen ) + 1 ;
}
2015-04-14 12:24:05 +00:00
targ = 0 ;
targ | = fl_hexen2 ? 1 : 0 ;
targ | = fl_ftetarg ? 2 : 0 ;
if ( * targs [ targ ] )
2005-02-28 07:16:19 +00:00
{
2015-04-14 12:24:05 +00:00
strcpy ( param + paramlen , targs [ targ ] ) ;
2005-02-28 07:16:19 +00:00
argv [ argc + + ] = param + paramlen ;
paramlen + = strlen ( param + paramlen ) + 1 ;
}
2013-06-23 02:17:02 +00:00
if ( fl_nondfltopts )
2005-02-28 07:16:19 +00:00
{
2013-06-23 02:17:02 +00:00
for ( i = 0 ; optimisations [ i ] . enabled ; i + + ) //enabled is a pointer
{
if ( optimisations [ i ] . flags & FLAG_SETINGUI )
sprintf ( param + paramlen , " -O%s " , optimisations [ i ] . abbrev ) ;
else
sprintf ( param + paramlen , " -Ono-%s " , optimisations [ i ] . abbrev ) ;
argv [ argc + + ] = param + paramlen ;
paramlen + = strlen ( param + paramlen ) + 1 ;
}
2005-02-28 07:16:19 +00:00
}
2005-03-22 23:47:49 +00:00
for ( i = 0 ; compiler_flag [ i ] . enabled ; i + + ) //enabled is a pointer
{
if ( compiler_flag [ i ] . flags & FLAG_SETINGUI )
sprintf ( param + paramlen , " -F%s " , compiler_flag [ i ] . abbrev ) ;
else
sprintf ( param + paramlen , " -Fno-%s " , compiler_flag [ i ] . abbrev ) ;
argv [ argc + + ] = param + paramlen ;
paramlen + = strlen ( param + paramlen ) + 1 ;
}
2005-02-28 07:16:19 +00:00
/* while(*args)
{
while ( * args < = ' ' & & * args )
args + + ;
for ( next = args ; * next > ' ' ; next + + )
;
strncpy ( param + paramlen , args , next - args ) ;
param [ paramlen + next - args ] = ' \0 ' ;
argv [ argc + + ] = param + paramlen ;
paramlen + = strlen ( param + paramlen ) + 1 ;
args = next ;
} */
2016-09-08 19:04:35 +00:00
// if (*forceoutputfile)
// {
// argv[argc++] = "-destfile";
// argv[argc++] = forceoutputfile;
// }
2005-02-28 07:16:19 +00:00
if ( * progssrcname )
{
argv [ argc + + ] = " -srcfile " ;
argv [ argc + + ] = progssrcname ;
}
if ( * progssrcdir )
{
argv [ argc + + ] = " -src " ;
argv [ argc + + ] = progssrcdir ;
}
2017-03-04 19:36:06 +00:00
while ( * args )
{
while ( * args < = ' ' & & * args )
args + + ;
for ( next = args ; * next > ' ' ; next + + )
;
strncpy ( param + paramlen , args , next - args ) ;
param [ paramlen + next - args ] = ' \0 ' ;
argv [ argc + + ] = param + paramlen ;
paramlen + = strlen ( param + paramlen ) + 1 ;
args = next ;
}
2005-02-28 07:16:19 +00:00
return argc ;
2004-08-25 03:42:49 +00:00
}
2019-01-20 01:00:18 +00:00
pbool GenBuiltinsList ( char * buffer , int buffersize )
{
QCC_def_t * def ;
int usedbuffer = 0 ;
int l ;
int fno ;
for ( fno = 0 ; fno < sourcefilesnumdefs ; fno + + )
{
for ( def = sourcefilesdefs [ fno ] ; def ; def = def - > next )
{
if ( def - > scope )
continue ; //ignore locals, because we don't know where we are, and they're probably irrelevent.
//if its a builtin function...
if ( def - > type - > type = = ev_function & & def - > symboldata - > function & & functions [ def - > symboldata - > function ] . code < 0 )
;
else if ( def - > filen & & strstr ( def - > filen , " extensions " ) )
;
else
continue ;
//but ignore it if its one of those special things that you're not meant to know about.
if ( strcmp ( def - > name , " IMMEDIATE " ) & & ! strchr ( def - > name , ' : ' ) & & ! strchr ( def - > name , ' . ' ) & & ! strchr ( def - > name , ' * ' ) & & ! strchr ( def - > name , ' [ ' ) )
{
l = strlen ( def - > name ) ;
if ( l & & usedbuffer + 2 + l < buffersize )
{
if ( usedbuffer )
buffer [ usedbuffer + + ] = ' ' ;
memcpy ( buffer + usedbuffer , def - > name , l ) ;
usedbuffer + = l ;
}
}
}
}
buffer [ usedbuffer ] = 0 ;
return usedbuffer > 0 ;
}
void QCC_CloseAllVFiles ( void )
{
vfile_t * f ;
while ( qcc_vfiles )
{
f = qcc_vfiles ;
qcc_vfiles = f - > next ;
free ( f - > file ) ;
free ( f ) ;
}
qcc_vfiles_changed = false ;
}
vfile_t * QCC_FindVFile ( const char * name )
{
vfile_t * f ;
for ( f = qcc_vfiles ; f ; f = f - > next )
{
if ( ! strcmp ( f - > filename , name ) )
return f ;
}
//give it another go, for case
for ( f = qcc_vfiles ; f ; f = f - > next )
{
if ( ! QC_strcasecmp ( f - > filename , name ) )
return f ;
}
return NULL ;
}
vfile_t * QCC_AddVFile ( const char * name , void * data , size_t size )
{
vfile_t * f = QCC_FindVFile ( name ) ;
if ( ! f )
{
f = malloc ( sizeof ( vfile_t ) + strlen ( name ) ) ;
f - > next = qcc_vfiles ;
strcpy ( f - > filename , name ) ;
qcc_vfiles = f ;
}
else
free ( f - > file ) ;
f - > file = malloc ( size ) ;
f - > type = FT_CODE ;
memcpy ( f - > file , data , size ) ;
f - > size = f - > bufsize = size ;
qcc_vfiles_changed = true ;
return f ;
}
void QCC_CatVFile ( vfile_t * f , const char * fmt , . . . )
{
va_list argptr ;
2020-03-15 06:58:03 +00:00
char msg [ 65536 ] ;
2019-01-20 01:00:18 +00:00
size_t n ;
va_start ( argptr , fmt ) ;
QC_vsnprintf ( msg , sizeof ( msg ) - 1 , fmt , argptr ) ;
va_end ( argptr ) ;
n = strlen ( msg ) ;
if ( f - > size + n > f - > bufsize )
{
size_t msize = f - > bufsize + n + 8192 ;
f - > file = realloc ( f - > file , msize ) ;
f - > bufsize = msize ;
}
memcpy ( ( char * ) f - > file + f - > size , msg , n ) ;
f - > size + = n ;
}
void QCC_InsertVFile ( vfile_t * f , size_t pos , const char * fmt , . . . )
{
va_list argptr ;
2020-03-15 06:58:03 +00:00
char msg [ 65536 ] ;
2019-01-20 01:00:18 +00:00
size_t n ;
va_start ( argptr , fmt ) ;
QC_vsnprintf ( msg , sizeof ( msg ) - 1 , fmt , argptr ) ;
va_end ( argptr ) ;
n = strlen ( msg ) ;
if ( f - > size + n > f - > bufsize )
{
size_t msize = f - > bufsize + n + 8192 ;
f - > file = realloc ( f - > file , msize ) ;
f - > bufsize = msize ;
}
memmove ( ( char * ) f - > file + pos + n , ( char * ) f - > file + pos , f - > size - pos ) ;
f - > size + = n ;
memcpy ( ( char * ) f - > file + pos , msg , n ) ;
}