1
0
Fork 0
mirror of https://github.com/galaxyhaxz/devilution synced 2025-02-16 11:35:50 +00:00
devilution/2020_03_31/Utils/MakeText/maketext.c
PrisonOfMirrors b720183846 initial up
2020-11-28 18:24:54 -06:00

319 lines
5.8 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 1 megabyte
#define BUFFER_SIZE_LIMIT (1 * 1024 * 1024)
// prevent including duplicate files
#define MAX_INCLUDE_FILES 256
char IncludedNames[MAX_INCLUDE_FILES][256];
unsigned char *ConvertEOL(unsigned char *p, int bufsize, int *newsize)
{
int i;
unsigned char *p2;
p2 = (unsigned char *)malloc(sizeof(unsigned char) * (bufsize + 1));
*newsize = 0;
for(i = 0; i < bufsize; i++) {
if(p[i] == '\r') {
p2[(*newsize)++] = '\n';
if(p[i + 1] == '\n') {
i++;
}
} else {
p2[(*newsize)++] = p[i];
}
}
p2[(*newsize)++] = '\0';
return p2;
}
unsigned char *RemoveWhitespace(unsigned char *p2, int fsize)
{
unsigned char *p, *p3, *p4;
p = (unsigned char *)malloc(sizeof(unsigned char) * (fsize + 1));
p3 = p;
p4 = p2;
while(*p4 != '\0') {
while(*p4 == ' ' || *p4 == '\t' || *p4 == '\n') {
p4++;
}
while(*p4 != '\n') {
*p3++ = *p4++;
}
*p3++ = *p4++;
}
*p3++ = '\0';
return p;
}
unsigned char *LoadBinaryFile(char *file, int *pdwSize)
{
unsigned char *p;
FILE *fp;
int bufsize;
fp = fopen(file, "rb");
if(fp == NULL) {
fprintf(stderr, "Can't open file %s\n", file);
exit(-1);
}
fseek(fp, 0L, SEEK_END);
bufsize = ftell(fp);
p = (unsigned char *)malloc(sizeof(unsigned char) * (bufsize + 1));
fseek(fp, 0L, SEEK_SET);
fread(p, sizeof(char), bufsize, fp);
fclose(fp);
if(pdwSize != NULL) {
*pdwSize = bufsize;
}
return p;
}
unsigned char *LoadTextFile(char *file, int *pdwSize)
{
unsigned char *p, *p2;
int bufsize, fsize;
p = LoadBinaryFile(file, &bufsize);
p2 = ConvertEOL(p, bufsize, &fsize);
free(p);
p = RemoveWhitespace(p2, fsize);
free(p2);
if(pdwSize != NULL) {
*pdwSize = fsize;
}
return p;
}
/*
* TODO: make recursive so all files with includes will expand into data buffer
* - currently only the main file may call the include function
*/
unsigned char *ExpandTextFile(unsigned char *p, int *fsize)
{
char FileName[256];
char Include[] = "#include";
int i, size, index;
unsigned char *p2, *p3, *p4, *pInclude;
p2 = (unsigned char *)malloc(sizeof(unsigned char) * (BUFFER_SIZE_LIMIT + 1));
p3 = p2;
*fsize = 0;
index = 0;
while(*p != '\0') {
if(strncmp(p, Include, sizeof(Include) - 1) == 0) {
p += sizeof(Include) - 1;
while(*p == ' ' || *p == '\t') {
p++;
}
if(*p != '"') {
fprintf(stderr, "Invalid file name\n");
exit(-1);
}
p++;
i = 0;
while(*p != '\n') {
FileName[i++] = *p++;
if(i >= sizeof(FileName)) {
fprintf(stderr, "File name exceeds max path\n");
exit(-1);
}
}
p++;
if(FileName[i - 1] != '"') {
fprintf(stderr, "Invalid file name: %s\n", FileName);
exit(-1);
}
FileName[i - 1] = '\0';
for(i = 0; IncludedNames[i][0] != '\0'; i++) {
if(strcmp(IncludedNames[i], FileName) == 0) {
fprintf(stderr, "File %s already included\n", FileName);
exit(-1);
}
}
strcpy(IncludedNames[index++], FileName);
if(index >= MAX_INCLUDE_FILES) {
fprintf(stderr, "Including too many files\n");
exit(-1);
}
pInclude = LoadTextFile(FileName, &size);
p4 = pInclude;
while(*p4 != '\0') {
if(p4[0] == '/' && p4[1] == '/') {
p4 += 2;
while(*p4 != '\n') {
p4++;
}
p4++;
} else {
(*fsize)++;
*p3++ = *p4++;
}
}
free(pInclude);
} else if(p[0] == '/' && p[1] == '/') {
p += 2;
while(*p != '\n') {
p++;
}
p++;
} else {
while(*p != '\n') {
(*fsize)++;
*p3++ = *p++;
}
(*fsize)++;
*p3++ = *p++;
}
if(*fsize >= BUFFER_SIZE_LIMIT) {
fprintf(stderr, "Exceeded buffer size limit\n");
exit(-1);
}
}
(*fsize)++;
*p3++ = *p++;
return p2;
}
void WriteDataFile(char *file, unsigned char *p, int fsize)
{
FILE *fp;
int i;
char Pre[] = "\t{ ";
char Suf[] = " },\r\n";
char Sep[] = ", ";
fp = fopen(file, "wb");
if(fp == NULL) {
fprintf(stderr, "Can't create file %s\n", file);
exit(-1);
}
while(*p != '\0') {
if(*p == '[') {
p++;
while(*p != ']' && *p != '\n') {
p++;
}
if(*p != ']') {
fprintf(stderr, "Error: invalid text entry\n");
exit(-1);
}
p++;
while(*p != '\n') {
p++;
}
p++;
fwrite(Pre, sizeof(char), sizeof(Pre) - 1, fp);
for(i = 0; i < 4; i++) {
if(*p == '[') {
fprintf(stderr, "Error: unexpected text entry\n");
exit(-1);
}
while(*p != '\n') {
fwrite(p, sizeof(char), 1, fp);
p++;
}
p++;
if(i < 4 - 1) {
fwrite(Sep, sizeof(char), sizeof(Sep) - 1, fp);
}
}
fwrite(Suf, sizeof(char), sizeof(Suf) - 1, fp);
} else {
fprintf(stderr, "Error: invalid text entry\n");
exit(-1);
}
}
fclose(fp);
}
void WriteEnumFile(char *file, unsigned char *p, int fsize)
{
int counter;
FILE *fp;
char EnumPre[] = "enum {\r\n";
char EnumSuf[] = "};\r\n";
char Tab[] = "\t";
char EFmt[] = " = %d,\r\n";
char Format[32];
fp = fopen(file, "wb");
if(fp == NULL) {
fprintf(stderr, "Can't create file %s\n", file);
exit(-1);
}
fwrite(EnumPre, sizeof(char), sizeof(EnumPre) - 1, fp);
counter = 0;
while(*p != '\0') {
if(*p == '[') {
p++;
fwrite(Tab, sizeof(char), sizeof(Tab) - 1, fp);
while(*p != ']') {
fwrite(p, sizeof(char), 1, fp);
p++;
}
p++;
sprintf(Format, EFmt, counter);
counter++;
fwrite(Format, sizeof(char), strlen(Format), fp);
while(*p != '\n') {
p++;
}
p++;
} else {
while(*p != '\n') {
p++;
}
p++;
}
}
fwrite(EnumSuf, sizeof(char), sizeof(EnumSuf) - 1, fp);
fclose(fp);
}
int main(int argc, char *argv[])
{
int size, fsize;
unsigned char *p, *p2;
if(argc != 4) {
fprintf(stderr, "Usage: maketext [txt] [cpp] [h]\n");
return 0;
}
p = LoadTextFile(argv[1], &size);
p2 = ExpandTextFile(p, &fsize);
WriteDataFile(argv[2], p2, fsize);
WriteEnumFile(argv[3], p2, fsize);
free(p);
free(p2);
return 0;
}