diff --git a/build/jam/FileRules b/build/jam/FileRules index 0ec5966692..292485b3dd 100644 --- a/build/jam/FileRules +++ b/build/jam/FileRules @@ -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) : data_to_source $(dataFile) ; + DataFileToSourceFile1 $(sourceFile) : data_to_source $(dataFile) ; + LocalClean clean : $(sourceFile) ; +} + +actions DataFileToSourceFile1 +{ + $(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR) + $(2[1]) $(DATA_VARIABLE) $(SIZE_VARIABLE) $(2[2]) $(1) +} diff --git a/src/tools/Jamfile b/src/tools/Jamfile index 029d4bfc15..d61420d287 100644 --- a/src/tools/Jamfile +++ b/src/tools/Jamfile @@ -30,6 +30,9 @@ BuildPlatformMain catattr : catattr.cpp : $(HOST_LIBBE) ; BuildPlatformMain copyattr : copyattr.cpp : $(HOST_LIBBE) $(HOST_LIBSTDC++) $(HOST_LIBSUPC++) ; +BuildPlatformMain data_to_source : data_to_source.cpp + : $(HOST_LIBSUPC++) ; + BuildPlatformMain listattr : listattr.cpp : $(HOST_LIBBE) ; if $(HOST_PLATFORM_BEOS_COMPATIBLE) { diff --git a/src/tools/data_to_source.cpp b/src/tools/data_to_source.cpp new file mode 100644 index 0000000000..adf5c51d28 --- /dev/null +++ b/src/tools/data_to_source.cpp @@ -0,0 +1,119 @@ +/* + * Copyright 2007, Ingo Weinhold . + * All rights reserved. Distributed under the terms of the MIT License. + */ + +#include +#include +#include +#include +#include +#include + + +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 \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; +}