
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <errno.h>

char *nametable[1000];
const char *infile = "object.h";
const char *outfile = "autogen/objnames.cpp";

// read data from a file until CR
void fgetline(FILE *fp, char *str, int maxlen)
{
int k;
	str[0] = 0;
	fgets(str, maxlen - 1, fp);
	
	// trim the CRLF that fgets appends
	for(k=strlen(str)-1;k>=0;k--)
	{
		if (str[k] != 13 && str[k] != 10) break;
		str[k] = 0;
	}
}


bool strbegin(const char *bigstr, const char *smallstr)
{
int i;

	for(i=0;smallstr[i];i++)
		if (bigstr[i] != smallstr[i]) return false;
	
	return true;
}


bool gen_table(void)
{
FILE *fp, *fpo;
char line[1024];
int nobjects = -1;
int count = 0;

	printf("regenerating object-names table...\n");
	
	fp = fopen(infile, "rb");
	if (!fp)
	{
		fprintf(stderr, "<Cannot open object.h>\n");
		return 1;
	}
	
	fpo = fileopen(outfile, "wb");
	if (!fpo)
	{
		fprintf(stderr, "<Cannot open objnames.cpp>\n");
		fclose(fp);
		return 1;
	}
	
	memset(nametable, 0, sizeof(nametable));
	
	while(!feof(fp))
	{
		fgetline(fp, line, sizeof(line));
		
		if (strbegin(line, "#define OBJ_"))
		{
			char *ptr = strstr(line, "//");
			if (ptr) *ptr = 0;
			
			strtok(line, " \t");
			const char *obj_name = strtok(NULL, " \t");
			const char *obj_number_str = strtok(NULL, " \t");
			int obj_number;
			
			if (obj_name && obj_number_str && (obj_number = atoi(obj_number_str)))
			{
				if (!strcmp(obj_name, "OBJ_LAST"))
				{
					nobjects = obj_number;
				}
				else
				{
					//printf("obj_name: %s   obj_number: %d\n", obj_name, obj_number);
					nametable[obj_number] = strdup(&obj_name[4]);
					count++;
				}
			}
		}
	}
	
	if (nobjects == -1)
	{
		fprintf(stderr, "Couldn't find OBJ_LAST\n");
		fclose(fp);
		fclose(fpo);
		return 1;
	}
	
	fprintf(fpo, "\n// auto-generated by genobjnametable.cpp\n");
	fprintf(fpo, "#include <stdio.h>\n");
	fprintf(fpo, "\nconst char *object_names[] = {\n");
	
	for(int i=0;i<nobjects;i++)
	{
		if (nametable[i])
		{
			fprintf(fpo, "\t\"%s\"", nametable[i]);
			free(nametable[i]);
		}
		else
		{
			fprintf(fpo, "\tNULL");
		}
		
		if (i+1 != nobjects)
			fprintf(fpo, ",\n");
		else
			fprintf(fpo, "\n");
	}
	
	fprintf(fpo, "};\n");
	printf("wrote %d objects in a space of %d\n", count, nobjects);
	
	fclose(fp);
	fclose(fpo);
	return 0;
}


int main(void)
{
struct stat instat;
struct stat outstat;

	if (stat(outfile, &outstat))
	{
		printf("names table missing\n");
		return gen_table();
	}
	
	if (stat(infile, &instat))
	{
		fprintf(stderr, "cannot stat '%s': error %d\n", infile, errno);
		return 1;
	}
	
	if (instat.st_mtime >= outstat.st_mtime)
	{
		return gen_table();
	}
	
	printf("table up to date\n");
	return 0;
}




