summaryrefslogblamecommitdiffstatshomepage
path: root/src/build/makelist.c
blob: 04327e78fe00d02d94f4f009350dcd7fb3264315 (plain) (tree)
1
2
3
4
5
6
7
8

                                





                                                                            





                                                                            
                     

 


                                             













                                                       






                                                   


                                                        

                     

                                                   
                                            


                                                   
                                   
 
                           

                                                        




                                                                              
 
                                             

                                               




                                   
 







                                                     
 


                                  
 






                                                             
 


                                                        
 






                                               
 






                                                                                 
 


                                               

                                           






                                                                                                                          

                                 









                                                                                                                          
                                                                    

                                 
 








                                                                                                                  
 






                                                                                                                                  
                 

                                     

                                                                   
         
 

                 

 


                                                   
 










                                                   
 


                                      
                                                       
                                
                         
 
                         
                                  



                                                      
                                                                
 
                                                 
                                    
 
                        
                                                                              
 

                                         
                                              
 
                                           
                                                              



                                                              
                                                                                                    
                      

                                                                                                            

                       
 
                                     
                                                                            


                 
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************

    makelist.c

    Create and sort the driver list.

***************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "corefile.h"
#include "cstrpool.h"


static dynamic_array<const char *> drivlist;
static dynamic_array<const char *> ignorelst;
static const_string_pool string_pool;


//-------------------------------------------------
//  driver_sort_callback - compare two items in
//  a string array
//-------------------------------------------------

int sort_callback(const void *elem1, const void *elem2)
{
	const char **item1 = (const char **)elem1;
	const char **item2 = (const char **)elem2;
	return strcmp(*item1, *item2);
}

//-------------------------------------------------
//  isignored - return info if item is in ignore
//  list or not
//-------------------------------------------------

bool isignored(const char *drivname)
{
	for (int i = 0; i < ignorelst.count(); i++)
		if (strcmp(ignorelst[i], drivname) == 0)
			return true;
	return false;
}

//-------------------------------------------------
//  parse_file - parse a single file, may be
//  called recursively
//-------------------------------------------------

int parse_file(const char *srcfile)
{
	// read source file
	dynamic_buffer buffer;
	file_error filerr = core_fload(srcfile, buffer);
	if (filerr != FILERR_NONE)
	{
		fprintf(stderr, "Unable to read source file '%s'\n", srcfile);
		return 1;
	}

	// rip through it to find all drivers
	char *srcptr = (char *)&buffer[0];
	char *endptr = srcptr + buffer.count();
	int linenum = 1;
	bool in_comment = false;
	while (srcptr < endptr)
	{
		char c = *srcptr++;

		// count newlines
		if (c == 13 || c == 10)
		{
			if (c == 13 && *srcptr == 10)
				srcptr++;
			linenum++;
			continue;
		}

		// skip any spaces
		if (isspace(c))
			continue;

		// look for end of C comment
		if (in_comment && c == '*' && *srcptr == '/')
		{
			srcptr++;
			in_comment = false;
			continue;
		}

		// skip anything else inside a C comment
		if (in_comment)
			continue;

		// look for start of C comment
		if (c == '/' && *srcptr == '*')
		{
			srcptr++;
			in_comment = true;
			continue;
		}

		// if we hit a C++ comment, scan to the end of line
		if (c == '/' && *srcptr == '/')
		{
			while (srcptr < endptr && *srcptr != 13 && *srcptr != 10)
				srcptr++;
			continue;
		}

		// look for an import directive
		if (c == '#')
		{
			char filename[256];
			filename[0] = 0;
			for (int pos = 0; srcptr < endptr && pos < ARRAY_LENGTH(filename) - 1 && !isspace(*srcptr); pos++)
			{
				filename[pos] = *srcptr++;
				filename[pos+1] = 0;
			}
			fprintf(stderr, "Importing drivers from '%s'\n", filename);
			parse_file(filename);
			continue;
		}
		if (c == '!')
		{
			char drivname[256];
			drivname[0] = 0;
			for (int pos = 0; srcptr < endptr && pos < ARRAY_LENGTH(drivname) - 1 && !isspace(*srcptr); pos++)
			{
				drivname[pos] = *srcptr++;
				drivname[pos+1] = 0;
			}
			fprintf(stderr, "Place driver '%s' to ignore list\n", drivname);
			ignorelst.append(string_pool.add(drivname));
			continue;
		}

		// otherwise treat as a driver name
		char drivname[32];
		drivname[0] = 0;
		srcptr--;
		for (int pos = 0; srcptr < endptr && pos < ARRAY_LENGTH(drivname) - 1 && !isspace(*srcptr); pos++)
		{
			drivname[pos] = *srcptr++;
			drivname[pos+1] = 0;
		}

		// verify the name as valid
		for (char *drivch = drivname; *drivch != 0; drivch++)
		{
			if ((*drivch >= 'a' && *drivch <= 'z') || (*drivch >= '0' && *drivch <= '9') || *drivch == '_')
				continue;
			fprintf(stderr, "%s:%d - Invalid character '%c' in driver \"%s\"\n", srcfile, linenum, *drivch, drivname);
			return 1;
		}

		// add it to the list
		if (!isignored(drivname))
			drivlist.append(string_pool.add(drivname));
	}

	return 0;
}


//-------------------------------------------------
//  main - primary entry point
//-------------------------------------------------

int main(int argc, char *argv[])
{
	// needs at least 1 argument
	if (argc < 2)
	{
		fprintf(stderr,
			"Usage:\n"
			"  makelist <source.lst>\n"
		);
		return 0;
	}

	// extract arguments
	const char *srcfile = argv[1];

	// parse the root file, exit early upon failure
	if (parse_file(srcfile))
		return 1;

	// output a count
	if (drivlist.count() == 0)
	{
		fprintf(stderr, "No drivers found\n");
		return 1;
	}
	fprintf(stderr, "%d drivers found\n", drivlist.count());

	// add a reference to the ___empty driver
	drivlist.append("___empty");

	// sort the list
	qsort(drivlist, drivlist.count(), sizeof(drivlist[0]), sort_callback);

	// start with a header
	printf("#include \"emu.h\"\n\n");
	printf("#include \"drivenum.h\"\n\n");

	// output the list of externs first
	for (int index = 0; index < drivlist.count(); index++)
		printf("GAME_EXTERN(%s);\n", drivlist[index]);
	printf("\n");

	// then output the array
	printf("const game_driver * const driver_list::s_drivers_sorted[%d] =\n", drivlist.count());
	printf("{\n");
	for (int index = 0; index < drivlist.count(); index++)
		printf("\t&GAME_NAME(%s)%s\n", drivlist[index], (index == drivlist.count() - 1) ? "" : ",");
	printf("};\n");
	printf("\n");

	// also output a global count
	printf("int driver_list::s_driver_count = %d;\n", drivlist.count());

	return 0;
}