Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
94cef5522d
|
|||
|
921e5b0b92
|
|||
|
65714912c2
|
|||
|
9634d5e6cf
|
|||
|
fc13836423
|
10
build.sh
10
build.sh
@@ -26,12 +26,12 @@ TARGET_SYSTEM=linux
|
|||||||
|
|
||||||
# CMake Settings
|
# CMake Settings
|
||||||
CMAKEDIR="${SRCDIR}/cmake"
|
CMAKEDIR="${SRCDIR}/cmake"
|
||||||
CMAKETAG="v4.1.1"
|
CMAKETAG="v4.2.0"
|
||||||
CMAKEVCS="https://gitlab.kitware.com/cmake/cmake.git"
|
CMAKEVCS="https://gitlab.kitware.com/cmake/cmake.git"
|
||||||
|
|
||||||
# LLVM Settings
|
# LLVM Settings
|
||||||
LLVMDIR="${SRCDIR}/llvm"
|
LLVMDIR="${SRCDIR}/llvm"
|
||||||
LLVMTAG="llvmorg-21.1.3"
|
LLVMTAG="llvmorg-22.1.2"
|
||||||
LLVMVCS="https://github.com/llvm/llvm-project.git"
|
LLVMVCS="https://github.com/llvm/llvm-project.git"
|
||||||
|
|
||||||
# Mtools Settings
|
# Mtools Settings
|
||||||
@@ -41,12 +41,12 @@ MTOOLSVCS="https://github.com/xt-sys/mtools.git"
|
|||||||
|
|
||||||
# Ninja Settings
|
# Ninja Settings
|
||||||
NINJADIR="${SRCDIR}/ninja"
|
NINJADIR="${SRCDIR}/ninja"
|
||||||
NINJATAG="v1.13.1"
|
NINJATAG="v1.13.2"
|
||||||
NINJAVCS="https://github.com/ninja-build/ninja.git"
|
NINJAVCS="https://github.com/ninja-build/ninja.git"
|
||||||
|
|
||||||
# Wine Settings
|
# Wine Settings
|
||||||
WINEDIR="${SRCDIR}/wine"
|
WINEDIR="${SRCDIR}/wine"
|
||||||
WINETAG="wine-10.15"
|
WINETAG="wine-10.19"
|
||||||
WINEVCS="https://github.com/wine-mirror/wine.git"
|
WINEVCS="https://github.com/wine-mirror/wine.git"
|
||||||
|
|
||||||
|
|
||||||
@@ -408,7 +408,7 @@ xtchain_build()
|
|||||||
echo ">>> Building XTchain tools ..."
|
echo ">>> Building XTchain tools ..."
|
||||||
mkdir -p ${BINDIR}/bin
|
mkdir -p ${BINDIR}/bin
|
||||||
mkdir -p ${BINDIR}/lib/xtchain
|
mkdir -p ${BINDIR}/lib/xtchain
|
||||||
for EXEC in bin2c diskimg exetool xtcspecc; do
|
for EXEC in bin2c diskimg exetool xtadkgen xtcspecc; do
|
||||||
if [ ! -e ${BINDIR}/bin/${EXEC} ]; then
|
if [ ! -e ${BINDIR}/bin/${EXEC} ]; then
|
||||||
${CCOMPILER} ${WRKDIR}/tools/${EXEC}.c -o ${BINDIR}/bin/${EXEC}
|
${CCOMPILER} ${WRKDIR}/tools/${EXEC}.c -o ${BINDIR}/bin/${EXEC}
|
||||||
fi
|
fi
|
||||||
|
|||||||
149
tools/diskimg.c
149
tools/diskimg.c
@@ -244,6 +244,8 @@ int main(int argc, char **argv)
|
|||||||
long FormatPartition = 0;
|
long FormatPartition = 0;
|
||||||
long DiskSizeBytes = 0;
|
long DiskSizeBytes = 0;
|
||||||
long DiskSizeMB = 0;
|
long DiskSizeMB = 0;
|
||||||
|
long MergedSize = 0;
|
||||||
|
long PreloaderSize = 0;
|
||||||
long SectorsToWrite = 0;
|
long SectorsToWrite = 0;
|
||||||
long VbrExtraSector = -1;
|
long VbrExtraSector = -1;
|
||||||
long VbrFileSize = -1;
|
long VbrFileSize = -1;
|
||||||
@@ -254,9 +256,12 @@ int main(int argc, char **argv)
|
|||||||
char Zero[SECTOR_SIZE] = {0};
|
char Zero[SECTOR_SIZE] = {0};
|
||||||
uint8_t Mbr[SECTOR_SIZE] = {0};
|
uint8_t Mbr[SECTOR_SIZE] = {0};
|
||||||
uint8_t ImageVbr[SECTOR_SIZE * 2] = {0};
|
uint8_t ImageVbr[SECTOR_SIZE * 2] = {0};
|
||||||
uint8_t *FullVbr = NULL;
|
uint8_t *MergedData = NULL;
|
||||||
|
uint8_t *PreloaderData = NULL;
|
||||||
|
uint8_t *FullVbrData = NULL;
|
||||||
const char *FileName = NULL;
|
const char *FileName = NULL;
|
||||||
const char *MbrFile = NULL;
|
const char *MbrFile = NULL;
|
||||||
|
const char *PreloadFile = NULL;
|
||||||
const char *VbrFile = NULL;
|
const char *VbrFile = NULL;
|
||||||
const char *CopyDir = NULL;
|
const char *CopyDir = NULL;
|
||||||
|
|
||||||
@@ -294,6 +299,11 @@ int main(int argc, char **argv)
|
|||||||
/* Output file */
|
/* Output file */
|
||||||
FileName = argv[++Index];
|
FileName = argv[++Index];
|
||||||
}
|
}
|
||||||
|
else if(strcmp(argv[Index], "-p") == 0 && Index + 1 < argc)
|
||||||
|
{
|
||||||
|
/* Preloader file */
|
||||||
|
PreloadFile = argv[++Index];
|
||||||
|
}
|
||||||
else if(strcmp(argv[Index], "-s") == 0 && Index + 1 < argc)
|
else if(strcmp(argv[Index], "-s") == 0 && Index + 1 < argc)
|
||||||
{
|
{
|
||||||
/* Disk size */
|
/* Disk size */
|
||||||
@@ -316,7 +326,15 @@ int main(int argc, char **argv)
|
|||||||
if(DiskSizeMB <= 0 || FileName == NULL)
|
if(DiskSizeMB <= 0 || FileName == NULL)
|
||||||
{
|
{
|
||||||
/* Missing required arguments, print usage */
|
/* Missing required arguments, print usage */
|
||||||
fprintf(stderr, "Usage: %s -o <output.img> -s <size_MB> [-b <sector>] [-c <dir>] [-f 16|32] [-m <mbr.img>] [-v <vbr.img>]\n", argv[0]);
|
fprintf(stderr, "Usage: %s -o <output.img> -s <size_MB> [-b <sector>] [-c <dir>] [-f 16|32] [-m <mbr.img>] [-p <preload.bin>] [-v <vbr.img>]\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate preload usage */
|
||||||
|
if(PreloadFile && !VbrFile)
|
||||||
|
{
|
||||||
|
/* Preloader code specified without VBR */
|
||||||
|
fprintf(stderr, "Error: Option -p (PRELOADER code) requires -v (VBR code) to be specified as well.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -485,7 +503,7 @@ int main(int argc, char **argv)
|
|||||||
VbrFileSize = GetSectorFileSize(VbrFile);
|
VbrFileSize = GetSectorFileSize(VbrFile);
|
||||||
if(VbrFileSize < 0)
|
if(VbrFileSize < 0)
|
||||||
{
|
{
|
||||||
/* The GetFileSize function already prints a perror message */
|
/* Unable to determine VBR file size */
|
||||||
perror("Could not get size of VBR file\n");
|
perror("Could not get size of VBR file\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -494,27 +512,28 @@ int main(int argc, char **argv)
|
|||||||
if(VbrFileSize % SECTOR_SIZE != 0)
|
if(VbrFileSize % SECTOR_SIZE != 0)
|
||||||
{
|
{
|
||||||
/* Unable to determine VBR file size */
|
/* Unable to determine VBR file size */
|
||||||
perror("Failed to determine VBR file size");
|
perror("VBR file size is not a multiple of sector size\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Calculate number of VBR sectors */
|
||||||
VbrTotalSectors = VbrFileSize / SECTOR_SIZE;
|
VbrTotalSectors = VbrFileSize / SECTOR_SIZE;
|
||||||
|
|
||||||
/* Allocate memory for the entire VBR file */
|
/* Allocate memory for the entire VBR file */
|
||||||
FullVbr = malloc(VbrFileSize);
|
FullVbrData = malloc(VbrFileSize);
|
||||||
if(!FullVbr)
|
if(!FullVbrData)
|
||||||
{
|
{
|
||||||
/* Memory allocation failed */
|
/* Memory allocation failed */
|
||||||
perror("Failed to allocate memory for VBR file");
|
perror("Failed to allocate memory for VBR file\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the entire VBR file into the buffer */
|
/* Read the entire VBR file into the buffer */
|
||||||
if(LoadSectors(VbrFile, FullVbr, VbrTotalSectors) != 0)
|
if(LoadSectors(VbrFile, FullVbrData, VbrTotalSectors) != 0)
|
||||||
{
|
{
|
||||||
/* Failed to load VBR from file */
|
/* Failed to load VBR from file */
|
||||||
perror("Failed to load VBR from file");
|
perror("Failed to load VBR from file\n");
|
||||||
free(FullVbr);
|
free(FullVbrData);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -523,8 +542,8 @@ int main(int argc, char **argv)
|
|||||||
if(fread(ImageVbr, 1, SECTOR_SIZE, File) != SECTOR_SIZE)
|
if(fread(ImageVbr, 1, SECTOR_SIZE, File) != SECTOR_SIZE)
|
||||||
{
|
{
|
||||||
/* Failed to read VBR from disk image */
|
/* Failed to read VBR from disk image */
|
||||||
perror("Failed to read BPB from disk image");
|
perror("Failed to read BPB from disk image\n");
|
||||||
free(FullVbr);
|
free(FullVbrData);
|
||||||
fclose(File);
|
fclose(File);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -533,21 +552,21 @@ int main(int argc, char **argv)
|
|||||||
if(FatFormat == 32)
|
if(FatFormat == 32)
|
||||||
{
|
{
|
||||||
/* For FAT32, BPB is larger (up to offset 89) */
|
/* For FAT32, BPB is larger (up to offset 89) */
|
||||||
memcpy(&FullVbr[3], &ImageVbr[3], 87);
|
memcpy(&FullVbrData[3], &ImageVbr[3], 87);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* For FAT16, BPB is smaller (up to offset 61) */
|
/* For FAT16, BPB is smaller (up to offset 61) */
|
||||||
memcpy(&FullVbr[3], &ImageVbr[3], 59);
|
memcpy(&FullVbrData[3], &ImageVbr[3], 59);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write the first 512 bytes of the final, merged VBR to the start of the partition */
|
/* Write the first 512 bytes of the final, merged VBR to the start of the partition */
|
||||||
fseek(File, Partition.StartLBA * SECTOR_SIZE, SEEK_SET);
|
fseek(File, Partition.StartLBA * SECTOR_SIZE, SEEK_SET);
|
||||||
if(fwrite(FullVbr, 1, SECTOR_SIZE, File) != SECTOR_SIZE)
|
if(fwrite(FullVbrData, 1, SECTOR_SIZE, File) != SECTOR_SIZE)
|
||||||
{
|
{
|
||||||
/* Failed to write VBR to disk image */
|
/* Failed to write VBR to disk image */
|
||||||
perror("Failed to write VBR to disk image");
|
perror("Failed to write VBR to disk image\n");
|
||||||
free(FullVbr);
|
free(FullVbrData);
|
||||||
fclose(File);
|
fclose(File);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -555,6 +574,72 @@ int main(int argc, char **argv)
|
|||||||
/* Handle extra VBR data if it exists */
|
/* Handle extra VBR data if it exists */
|
||||||
if(FatFormat == 32)
|
if(FatFormat == 32)
|
||||||
{
|
{
|
||||||
|
/* Check if a preloader file was provided */
|
||||||
|
if(PreloadFile)
|
||||||
|
{
|
||||||
|
/* Get the size of the preloader file */
|
||||||
|
PreloaderSize = GetSectorFileSize(PreloadFile);
|
||||||
|
if(PreloaderSize < 0)
|
||||||
|
{
|
||||||
|
/* Unable to determine preloader file size */
|
||||||
|
perror("Could not get size of preloader file.\n");
|
||||||
|
free(FullVbrData);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if preloader size is multiple of 512 bytes */
|
||||||
|
if(PreloaderSize % SECTOR_SIZE != 0)
|
||||||
|
{
|
||||||
|
/* Preloader file size is not a multiple of 512 bytes */
|
||||||
|
perror("Preloader file size is not a multiple of sector size\n");
|
||||||
|
free(FullVbrData);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate buffer for preloader */
|
||||||
|
PreloaderData = malloc((size_t)PreloaderSize);
|
||||||
|
if(!PreloaderData)
|
||||||
|
{
|
||||||
|
/* Memory allocation failed */
|
||||||
|
perror("Failed to allocate memory for preloader");
|
||||||
|
free(FullVbrData);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load preloader data */
|
||||||
|
if(LoadSectors(PreloadFile, PreloaderData, PreloaderSize / SECTOR_SIZE) != 0)
|
||||||
|
{
|
||||||
|
/* Failed to load preloader data */
|
||||||
|
perror("Failed to load Preloader code from file\n");
|
||||||
|
free(FullVbrData);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate new buffer for the first 512 bytes of VBR and preloader */
|
||||||
|
MergedSize = SECTOR_SIZE + PreloaderSize;
|
||||||
|
MergedData = malloc(MergedSize);
|
||||||
|
if(!MergedData)
|
||||||
|
{
|
||||||
|
/* Memory allocation failed */
|
||||||
|
perror("Failed to allocate memory for Preloader file\n");
|
||||||
|
free(PreloaderData);
|
||||||
|
free(FullVbrData);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Merge VBR and preloader data */
|
||||||
|
memcpy(MergedData, FullVbrData, SECTOR_SIZE);
|
||||||
|
memcpy(MergedData + SECTOR_SIZE, PreloaderData, PreloaderSize);
|
||||||
|
|
||||||
|
/* Free old buffers and replace with merged data */
|
||||||
|
free(FullVbrData);
|
||||||
|
free(PreloaderData);
|
||||||
|
FullVbrData = MergedData;
|
||||||
|
|
||||||
|
/* Update VBR sectors count */
|
||||||
|
VbrTotalSectors = (MergedSize + SECTOR_SIZE - 1) / SECTOR_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if there is extra VBR data to write */
|
/* Check if there is extra VBR data to write */
|
||||||
if(VbrTotalSectors > 1)
|
if(VbrTotalSectors > 1)
|
||||||
{
|
{
|
||||||
@@ -569,7 +654,7 @@ int main(int argc, char **argv)
|
|||||||
/* Failed to find a safe sector */
|
/* Failed to find a safe sector */
|
||||||
fprintf(stderr, "Error: Could not automatically find a safe space in the FAT32 reserved region for %ld extra VBR sectors.\n",
|
fprintf(stderr, "Error: Could not automatically find a safe space in the FAT32 reserved region for %ld extra VBR sectors.\n",
|
||||||
sectors_to_write);
|
sectors_to_write);
|
||||||
free(FullVbr);
|
free(FullVbrData);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -583,7 +668,7 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
/* The remaining space is not large enough to fit the extra VBR data */
|
/* The remaining space is not large enough to fit the extra VBR data */
|
||||||
fprintf(stderr, "Error: VBR file is too large. Writing to sector %ld would exceed the FAT32 reserved region (32 sectors).\n", VbrLastSector);
|
fprintf(stderr, "Error: VBR file is too large. Writing to sector %ld would exceed the FAT32 reserved region (32 sectors).\n", VbrLastSector);
|
||||||
free(FullVbr);
|
free(FullVbrData);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -596,18 +681,18 @@ int main(int argc, char **argv)
|
|||||||
/* We are about to overwrite a critical sector */
|
/* We are about to overwrite a critical sector */
|
||||||
fprintf(stderr, "Error: Writing VBR extra data would overwrite critical sector %d (%s).\n",
|
fprintf(stderr, "Error: Writing VBR extra data would overwrite critical sector %d (%s).\n",
|
||||||
Fat32ReservedMap[Index].SectorNumber, Fat32ReservedMap[Index].Description);
|
Fat32ReservedMap[Index].SectorNumber, Fat32ReservedMap[Index].Description);
|
||||||
free(FullVbr);
|
free(FullVbrData);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write the rest of the VBR data */
|
/* Write the rest of the VBR data */
|
||||||
fseek(File, (Partition.StartLBA + VbrExtraSector) * SECTOR_SIZE, SEEK_SET);
|
fseek(File, (Partition.StartLBA + VbrExtraSector) * SECTOR_SIZE, SEEK_SET);
|
||||||
if(fwrite(FullVbr + SECTOR_SIZE, 1, SectorsToWrite * SECTOR_SIZE, File) != (size_t)(SectorsToWrite * SECTOR_SIZE))
|
if(fwrite(FullVbrData + SECTOR_SIZE, 1, SectorsToWrite * SECTOR_SIZE, File) != (size_t)(SectorsToWrite * SECTOR_SIZE))
|
||||||
{
|
{
|
||||||
/* Failed to write extra VBR data to disk image */
|
/* Failed to write extra VBR data to disk image */
|
||||||
perror("Failed to write extra VBR data to disk image");
|
perror("Failed to write extra VBR data to disk image");
|
||||||
free(FullVbr);
|
free(FullVbrData);
|
||||||
fclose(File);
|
fclose(File);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -616,17 +701,17 @@ int main(int argc, char **argv)
|
|||||||
else /* FatFormat == 16 */
|
else /* FatFormat == 16 */
|
||||||
{
|
{
|
||||||
/* Check if there is extra VBR data to write */
|
/* Check if there is extra VBR data to write */
|
||||||
if(VbrTotalSectors > 1)
|
if(VbrTotalSectors > 1 || PreloadFile)
|
||||||
{
|
{
|
||||||
/* FAT16 only supports a 1-sector VBR */
|
/* FAT16 only supports a 1-sector VBR */
|
||||||
fprintf(stderr, "Error: VBR file is %ld sectors, but FAT16 only supports a 1-sector VBR.\n", VbrTotalSectors);
|
fprintf(stderr, "Error: FAT16 does not support multi-sector VBR or preloader data.\n");
|
||||||
free(FullVbr);
|
free(FullVbrData);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free allocated memory */
|
/* Free allocated memory */
|
||||||
free(FullVbr);
|
free(FullVbrData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Close file */
|
/* Close file */
|
||||||
@@ -644,8 +729,16 @@ int main(int argc, char **argv)
|
|||||||
/* Compose VBR info string */
|
/* Compose VBR info string */
|
||||||
if(VbrExtraSector != -1)
|
if(VbrExtraSector != -1)
|
||||||
{
|
{
|
||||||
/* VBR with extra data */
|
if(PreloadFile)
|
||||||
snprintf(VbrInfo, sizeof(VbrInfo), ", VBR written (extra data at sector %ld)", VbrExtraSector);
|
{
|
||||||
|
/* Preloader written */
|
||||||
|
snprintf(VbrInfo, sizeof(VbrInfo), ", VBR written (preloader at sector %ld)", VbrExtraSector);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* VBR with extra data */
|
||||||
|
snprintf(VbrInfo, sizeof(VbrInfo), ", VBR written (extra data at sector %ld)", VbrExtraSector);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
166
tools/xtadkgen.c
Normal file
166
tools/xtadkgen.c
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
/**
|
||||||
|
* PROJECT: XTchain
|
||||||
|
* LICENSE: See COPYING.md in the top level directory
|
||||||
|
* FILE: tools/xtadkgen.c
|
||||||
|
* DESCRIPTION: XT Assembly Development Kit generator
|
||||||
|
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "xtchain.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define MAX_LINE_LEN 1024
|
||||||
|
#define MAGIC_MARKER "==> "
|
||||||
|
|
||||||
|
/* Prints usage */
|
||||||
|
void PrintUsage(const char* ProgramName)
|
||||||
|
{
|
||||||
|
/* Output usage instructions to stderr */
|
||||||
|
fprintf(stderr, "Usage: %s <input1.S> [input2.S ...] -o <output.h>\n", ProgramName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Processes single .S file */
|
||||||
|
void ProcessSourceFile(FILE* InFile, FILE* OutFile)
|
||||||
|
{
|
||||||
|
char LineBuffer[MAX_LINE_LEN];
|
||||||
|
char SymbolName[256];
|
||||||
|
char ValueString[256];
|
||||||
|
char *ValuePointer;
|
||||||
|
char *Marker;
|
||||||
|
|
||||||
|
/* Iterate through the input stream until the end of the file */
|
||||||
|
while(fgets(LineBuffer, sizeof(LineBuffer), InFile))
|
||||||
|
{
|
||||||
|
Marker = strstr(LineBuffer, MAGIC_MARKER);
|
||||||
|
|
||||||
|
/* Search for the predefined translation marker */
|
||||||
|
if(Marker)
|
||||||
|
{
|
||||||
|
/* Extract the symbol identifier and its associated value */
|
||||||
|
if(sscanf(Marker, "==> %255s %255s", SymbolName, ValueString) == 2)
|
||||||
|
{
|
||||||
|
/* Initialize pointer for character-level cleanup */
|
||||||
|
ValuePointer = ValueString;
|
||||||
|
|
||||||
|
/* Strip architecture-specific immediate prefixes such as '$' (AT&T) or '#' (ARM) */
|
||||||
|
while(*ValuePointer == '$' || *ValuePointer == '#')
|
||||||
|
{
|
||||||
|
/* Advance pointer to the first alpha-numeric character */
|
||||||
|
ValuePointer++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generate the corresponding C-preprocessor macro definition */
|
||||||
|
fprintf(OutFile, "#define %s %s\n", SymbolName, ValuePointer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Main function */
|
||||||
|
int main(int Argc, char* Argv[])
|
||||||
|
{
|
||||||
|
FILE* InFile;
|
||||||
|
FILE* OutFile = stdout;
|
||||||
|
const char* OutputName = NULL;
|
||||||
|
int FirstInputIndex = -1;
|
||||||
|
int InputCount = 0;
|
||||||
|
|
||||||
|
/* Validate that a minimum set of command-line arguments is present */
|
||||||
|
if(Argc < 2)
|
||||||
|
{
|
||||||
|
/* Display usage information and terminate on insufficient arguments */
|
||||||
|
PrintUsage(Argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse command-line arguments */
|
||||||
|
for(int Index = 1; Index < Argc; Index++)
|
||||||
|
{
|
||||||
|
/* Identify the output file switch */
|
||||||
|
if((strcmp(Argv[Index], "-o") == 0 || strcmp(Argv[Index], "-O") == 0) && Index + 1 < Argc)
|
||||||
|
{
|
||||||
|
/* Assign the designated output path and skip the next argument */
|
||||||
|
OutputName = Argv[++Index];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Track the first occurrence of an input file for the processing loop */
|
||||||
|
if(FirstInputIndex == -1)
|
||||||
|
{
|
||||||
|
/* Store the argument index for the subsequent file operations */
|
||||||
|
FirstInputIndex = Index;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Increment the total count of input files */
|
||||||
|
InputCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure at least one input source is available for processing */
|
||||||
|
if(InputCount == 0 || (OutputName == NULL && FirstInputIndex == -1))
|
||||||
|
{
|
||||||
|
/* Print usage and exit */
|
||||||
|
PrintUsage(Argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the output stream either to a file or default to stdout */
|
||||||
|
if(OutputName)
|
||||||
|
{
|
||||||
|
/* Attempt to open the specified output header for write access */
|
||||||
|
OutFile = fopen(OutputName, "w");
|
||||||
|
if(!OutFile)
|
||||||
|
{
|
||||||
|
/* Emit fatal error if the destination file cannot be accessed */
|
||||||
|
fprintf(stderr, "%s: Failed to open output file '%s'\n", Argv[0], OutputName);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write the auto-generation warning and inclusion guard */
|
||||||
|
fprintf(OutFile, "// FILE GENERATED AUTOMATICALLY BY '%s'. DO NOT EDIT!\n\n", Argv[0]);
|
||||||
|
fprintf(OutFile, "#ifndef __XTADK_H_\n");
|
||||||
|
fprintf(OutFile, "#define __XTADK_H_\n\n");
|
||||||
|
|
||||||
|
/* Loop through the arguments again to process each input file */
|
||||||
|
for(int Index = 1; Index < Argc; Index++)
|
||||||
|
{
|
||||||
|
/* Skip the output switch and its associated parameter */
|
||||||
|
if(strcmp(Argv[Index], "-o") == 0 || strcmp(Argv[Index], "-O") == 0)
|
||||||
|
{
|
||||||
|
/* Advance the loop counter and continue */
|
||||||
|
Index++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open the current assembly source file */
|
||||||
|
InFile = fopen(Argv[Index], "r");
|
||||||
|
if(!InFile)
|
||||||
|
{
|
||||||
|
/* Report error for the missing file and proceed to the next input file */
|
||||||
|
fprintf(stderr, "%s: Failed to open file '%s', skipping.\n", Argv[0], Argv[Index]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add source file data to the generated header */
|
||||||
|
fprintf(OutFile, "/* Source: %s */\n", Argv[Index]);
|
||||||
|
ProcessSourceFile(InFile, OutFile);
|
||||||
|
fprintf(OutFile, "\n");
|
||||||
|
|
||||||
|
/* Close the input file handle */
|
||||||
|
fclose(InFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close the inclusion guard in the output */
|
||||||
|
fprintf(OutFile, "#endif /* __XTADK_H_ */\n");
|
||||||
|
|
||||||
|
/* Check if a file handle was utilized */
|
||||||
|
if(OutFile != stdout)
|
||||||
|
{
|
||||||
|
/* Commit buffered data and close the output file */
|
||||||
|
fclose(OutFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return success */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user