Added small tool source_to_data, which takes an arbitrary data file and

generates a C source file defining an array variable containing the file's
data. DataFileToSourceFile is the respective jam rule.

The idea is to directly built the boot archive into the boot loader for
network booting (and thus avoiding to download it from somewhere). In
case of PXE this doesn't work, though, due to restrictions to the size
of the NBP. Maybe Open Firmware is less restrictive.



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21602 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2007-07-15 00:04:27 +00:00
parent b9fcbf7c74
commit 1485d7a2d7
3 changed files with 142 additions and 0 deletions

View File

@ -253,3 +253,23 @@ actions CopySetHaikuRevision1
$(2[2]) $(1) ${revision}
}
rule DataFileToSourceFile sourceFile : dataFile : dataVariable : sizeVariable
{
sourceFile = [ FGristFiles $(sourceFile) ] ;
MakeLocateCommonPlatform $(sourceFile) ;
sizeVariable ?= $(dataVariable)Size ;
DATA_VARIABLE on $(sourceFile) = $(dataVariable) ;
SIZE_VARIABLE on $(sourceFile) = $(sizeVariable) ;
Depends $(sourceFile) : <build>data_to_source $(dataFile) ;
DataFileToSourceFile1 $(sourceFile) : <build>data_to_source $(dataFile) ;
LocalClean clean : $(sourceFile) ;
}
actions DataFileToSourceFile1
{
$(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR)
$(2[1]) $(DATA_VARIABLE) $(SIZE_VARIABLE) $(2[2]) $(1)
}

View File

@ -30,6 +30,9 @@ BuildPlatformMain <build>catattr : catattr.cpp : $(HOST_LIBBE) ;
BuildPlatformMain <build>copyattr : copyattr.cpp
: $(HOST_LIBBE) $(HOST_LIBSTDC++) $(HOST_LIBSUPC++) ;
BuildPlatformMain <build>data_to_source : data_to_source.cpp
: $(HOST_LIBSUPC++) ;
BuildPlatformMain <build>listattr : listattr.cpp : $(HOST_LIBBE) ;
if $(HOST_PLATFORM_BEOS_COMPATIBLE) {

View File

@ -0,0 +1,119 @@
/*
* Copyright 2007, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
void
write_string(int fd, const char* data)
{
int len = strlen(data);
if (len == 0)
return;
ssize_t written = write(fd, data, len);
if (written < 0) {
fprintf(stderr, "Error: Failed to write to output file: %s\n",
strerror(errno));
exit(1);
}
}
int
main(int argc, const char* const* argv)
{
if (argc != 5) {
fprintf(stderr,
"Usage: %s <data var name> <size var name> <input> <output>\n",
argv[0]);
exit(1);
}
const char* dataVarName = argv[1];
const char* sizeVarName = argv[2];
const char* inFileName = argv[3];
const char* outFileName = argv[4];
// open files
int inFD = open(inFileName, O_RDONLY);
if (inFD < 0) {
fprintf(stderr, "Error: Failed to open input file \"%s\": %s\n",
inFileName, strerror(errno));
exit(1);
}
int outFD = open(outFileName, O_WRONLY | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (outFD < 0) {
fprintf(stderr, "Error: Failed to open output file \"%s\": %s\n",
outFileName, strerror(errno));
exit(1);
}
const int kCharsPerLine = 15;
const int kBufferSize = 16 * 1024;
unsigned char buffer[kBufferSize];
char lineBuffer[128];
sprintf(lineBuffer, "unsigned char %s[] = {\n", dataVarName);
write_string(outFD, lineBuffer);
off_t dataSize = 0;
off_t offset = 0;
char* lineBufferEnd = lineBuffer;
*lineBufferEnd = '\0';
while (true) {
// read a buffer
ssize_t bytesRead = read(inFD, buffer, kBufferSize);
if (bytesRead < 0) {
fprintf(stderr, "Error: Failed to read from input file: %s\n",
strerror(errno));
exit(1);
}
if (bytesRead == 0)
break;
dataSize += bytesRead;
// write lines
for (int i = 0; i < bytesRead; i++, offset++) {
if (offset % kCharsPerLine == 0) {
if (offset > 0) {
// line is full -- flush it
strcpy(lineBufferEnd, ",\n");
write_string(outFD, lineBuffer);
lineBufferEnd = lineBuffer;
*lineBufferEnd = '\0';
}
sprintf(lineBufferEnd, "\t%u", (unsigned)buffer[i]);
} else
sprintf(lineBufferEnd, ", %u", (unsigned)buffer[i]);
lineBufferEnd += strlen(lineBufferEnd);
}
}
// flush the line buffer
if (lineBufferEnd != lineBuffer) {
strcpy(lineBufferEnd, ",\n");
write_string(outFD, lineBuffer);
}
// close the braces and write the size variable
sprintf(lineBuffer, "};\nlong long %s = %lldLL;\n", sizeVarName,
dataSize);
write_string(outFD, lineBuffer);
close(inFD);
close(outFD);
return 0;
}