diff --git a/src/tools/rc/compile.cpp b/src/tools/rc/compile.cpp index 0e239f1021..c1c69c3ccb 100644 --- a/src/tools/rc/compile.cpp +++ b/src/tools/rc/compile.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -52,8 +53,7 @@ static jmp_buf abort_jmp; // for aborting compilation // parser properly frees up objects when it is done with them. #ifdef DEBUG -struct mem_t -{ +struct mem_t { void* ptr; char* file; int32 line; @@ -67,15 +67,42 @@ static mem_list_t mem_list; static ptr_list_t mem_list; #endif -//------------------------------------------------------------------------------ -void* alloc_mem(size_t size) +class AddIncludeDir { + public: + AddIncludeDir(const char *file); + ~AddIncludeDir(); + + private: + BPath fPath; +}; + + +AddIncludeDir::AddIncludeDir(const char *file) + : + fPath(file) { - void* ptr = malloc(size); // can be 0 + if (fPath.GetParent(&fPath) == B_OK) + rdef_add_include_dir(fPath.Path(), false); +} + + +AddIncludeDir::~AddIncludeDir() +{ + if (fPath.InitCheck() == B_OK) + rdef_remove_include_dir(fPath.Path()); +} + + +// #pragma mark - + + +void * +alloc_mem(size_t size) +{ + void *ptr = malloc(size); // can be 0 if (ptr == NULL) - { abort_compile(B_NO_MEMORY, "out of memory"); - } #ifdef DEBUG mem_t mem; @@ -90,17 +117,14 @@ void* alloc_mem(size_t size) return ptr; } -//------------------------------------------------------------------------------ -void free_mem(void* ptr) +void +free_mem(void *ptr) { - if (ptr != NULL) - { + if (ptr != NULL) { #ifdef DEBUG - for (mem_iter_t i = mem_list.begin(); i != mem_list.end(); ++i) - { - if (i->ptr == ptr) - { + for (mem_iter_t i = mem_list.begin(); i != mem_list.end(); ++i) { + if (i->ptr == ptr) { free(i->ptr); free(i->file); mem_list.erase(i); @@ -114,16 +138,15 @@ void free_mem(void* ptr) } } -//------------------------------------------------------------------------------ -static void clean_up_mem() +static void +clean_up_mem() { #ifdef DEBUG - if (mem_list.size() != 0) { + if (mem_list.size() != 0) printf("mem_list leaks %ld objects\n", mem_list.size()); - } - for (mem_iter_t i = mem_list.begin(); i != mem_list.end(); ) - { + + for (mem_iter_t i = mem_list.begin(); i != mem_list.end(); ) { printf("%p allocated at %s:%ld\n", i->ptr, i->file, i->line); free(i->ptr); free(i->file); @@ -134,9 +157,9 @@ static void clean_up_mem() #endif } -//------------------------------------------------------------------------------ -void abort_compile(status_t err, const char* format, ...) +void +abort_compile(status_t err, const char *format, ...) { va_list ap; @@ -151,22 +174,21 @@ void abort_compile(status_t err, const char* format, ...) abort_compile(); } -//------------------------------------------------------------------------------ -void abort_compile() +void +abort_compile() { longjmp(abort_jmp, 1); } -//------------------------------------------------------------------------------ -static void compile_file(char* file) +static void +compile_file(char *file) { strcpy(lexfile, file); yyin = fopen(lexfile, "r"); - if (yyin == NULL) - { + if (yyin == NULL) { strcpy(rdef_err_file, lexfile); rdef_err = RDEF_FILE_NOT_FOUND; return; @@ -175,8 +197,7 @@ static void compile_file(char* file) init_lexer(); init_parser(); - if (setjmp(abort_jmp) == 0) - { + if (setjmp(abort_jmp) == 0) { yyparse(); } @@ -191,76 +212,66 @@ static void compile_file(char* file) clean_up_mem(); } -//------------------------------------------------------------------------------ -static status_t open_output_file() +static status_t +open_output_file() { status_t err = entry.SetTo(rsrc_file, true); - if (err == B_OK) - { + if (err == B_OK) { uint32 openMode = B_READ_WRITE | B_CREATE_FILE; - bool clobber = false; + bool clobber = false; - if (!(flags & RDEF_MERGE_RESOURCES)) - { + if (!(flags & RDEF_MERGE_RESOURCES)) { openMode |= B_ERASE_FILE; clobber = true; } err = file.SetTo(&entry, openMode); if (err == B_OK) - { err = rsrc.SetTo(&file, clobber); - } } return err; } -//------------------------------------------------------------------------------ -static void close_output_file() +static void +close_output_file() { - if ((rdef_err == B_OK) || (flags & RDEF_MERGE_RESOURCES)) - { + if (rdef_err == B_OK || (flags & RDEF_MERGE_RESOURCES) != 0) rsrc.Sync(); - } else - { entry.Remove(); // throw away output file - } file.Unset(); entry.Unset(); } -//------------------------------------------------------------------------------ -status_t rdef_compile(const char* output_file) +status_t +rdef_compile(const char *outputFile) { clear_error(); - if ((output_file == NULL) || (output_file[0] == '\0')) - { + if (outputFile == NULL || outputFile[0] == '\0') { rdef_err = B_BAD_VALUE; return rdef_err; } - rsrc_file = output_file; + rsrc_file = outputFile; rdef_err = open_output_file(); if (rdef_err != B_OK) - { return rdef_err; - } for (ptr_iter_t i = input_files.begin(); - (i != input_files.end()) && (rdef_err == B_OK); ++i) - { - compile_file((char*) *i); + (i != input_files.end()) && (rdef_err == B_OK); ++i) { + char *path = (char *)*i; + + AddIncludeDir add(path); + compile_file(path); } close_output_file(); return rdef_err; } -//------------------------------------------------------------------------------ diff --git a/src/tools/rc/rc.cpp b/src/tools/rc/rc.cpp index 1c4c69b529..55bb1628a3 100644 --- a/src/tools/rc/rc.cpp +++ b/src/tools/rc/rc.cpp @@ -32,23 +32,23 @@ #define DEFAULT_OUT_RSRC "out.rsrc" #define DEFAULT_OUT_RDEF "out.rdef" -static char* prog_name; +extern const char *__progname; +static const char *sProgramName = __progname; static bool quiet = false; static bool should_decompile = false; static uint32 flags = 0; -static char output_file[B_PATH_NAME_LENGTH] = { 0 }; +static char sOutputFile[B_PATH_NAME_LENGTH] = { 0 }; -//------------------------------------------------------------------------------ -void warn(const char* format, ...) +void +warn(const char *format, ...) { va_list ap; - if (!quiet) - { - fprintf(stderr, "Warning! "); + if (!quiet) { + fprintf(stderr, "%s: Warning! ", sProgramName); va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap); @@ -56,15 +56,14 @@ void warn(const char* format, ...) } } -//------------------------------------------------------------------------------ -void error(const char* format, ...) +void +error(const char *format, ...) { va_list ap; - if (!quiet) - { - fprintf(stderr, "Error! "); + if (!quiet) { + fprintf(stderr, "%s: Error! ", sProgramName); va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap); @@ -74,146 +73,111 @@ void error(const char* format, ...) exit(EXIT_FAILURE); } -//------------------------------------------------------------------------------ -static void usage() +static void +usage() { - printf( - -"%s\n\n" -"To compile an rdef script into a resource file:\n" -" %s [options] [-o ] ...\n\n" -"To convert a resource file back into an rdef script:\n" -" %s [options] [-o ] -d ...\n\n" -"Options:\n" -" -d --decompile create an rdef script from a resource file\n" -" --auto-names construct resource names from ID symbols\n" -" -h --help show this message\n" -" -I --include add to the list of include paths\n" -" -m --merge do not erase existing contents of output file\n" -" -o --output specify output file name, default is out.xxx\n" -" -q --quiet do not display any error messages\n" -" -V --version show software version and license\n", - - TITLE, prog_name, prog_name); + printf("%s\n\n" + "To compile an rdef script into a resource file:\n" + " %s [options] [-o ] ...\n\n" + "To convert a resource file back into an rdef script:\n" + " %s [options] [-o ] -d ...\n\n" + "Options:\n" + " -d --decompile create an rdef script from a resource file\n" + " --auto-names construct resource names from ID symbols\n" + " -h --help show this message\n" + " -I --include add to the list of include paths\n" + " -m --merge do not erase existing contents of output file\n" + " -o --output specify output file name, default is out.xxx\n" + " -q --quiet do not display any error messages\n" + " -V --version show software version and license\n", + TITLE, sProgramName, sProgramName); exit(EXIT_SUCCESS); } -//------------------------------------------------------------------------------ -static void version() +static void +version() { - printf( - "%s\n\n" + printf("%s\n\n" "Copyright (c) 2003 Matthijs Hollemans\n\n" -"Permission is hereby granted, free of charge, to any person obtaining a\n" -"copy of this software and associated documentation files (the \"Software\"),\n" -"to deal in the Software without restriction, including without limitation\n" -"the rights to use, copy, modify, merge, publish, distribute, sublicense,\n" -"and/or sell copies of the Software, and to permit persons to whom the\n" -"Software is furnished to do so, subject to the following conditions:\n\n" + "Permission is hereby granted, free of charge, to any person obtaining a\n" + "copy of this software and associated documentation files (the \"Software\"),\n" + "to deal in the Software without restriction, including without limitation\n" + "the rights to use, copy, modify, merge, publish, distribute, sublicense,\n" + "and/or sell copies of the Software, and to permit persons to whom the\n" + "Software is furnished to do so, subject to the following conditions:\n\n" -"The above copyright notice and this permission notice shall be included in\n" -"all copies or substantial portions of the Software.\n\n" - -"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n" -"IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n" -"FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n" -"AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n" -"LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n" -"FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n" -"DEALINGS IN THE SOFTWARE.\n", + "The above copyright notice and this permission notice shall be included in\n" + "all copies or substantial portions of the Software.\n\n" + "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n" + "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n" + "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n" + "AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n" + "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n" + "FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n" + "DEALINGS IN THE SOFTWARE.\n", TITLE); exit(EXIT_SUCCESS); } -//------------------------------------------------------------------------------ -static void get_program_name(char* argv[]) -{ - char* p; - prog_name = ((p = strrchr(argv[0], '/')) ? p + 1 : *argv); -} - -//------------------------------------------------------------------------------ - -static void parse_options(int argc, char* argv[]) +static void +parse_options(int argc, char* argv[]) { int32 args_left = argc - 1; - for (int32 i = 1; i < argc; ++i) - { - if ((strcmp(argv[i], "-o") == 0) - || (strcmp(argv[i], "--output") == 0)) - { + for (int32 i = 1; i < argc; ++i) { + if (strcmp(argv[i], "-o") == 0 + || strcmp(argv[i], "--output") == 0) { if (i + 1 >= argc) - { error("%s should be followed by a file name", argv[i]); - } - strcpy(output_file, argv[i + 1]); + strcpy(sOutputFile, argv[i + 1]); argv[i] = NULL; argv[i + 1] = NULL; ++i; args_left -= 2; - } - else if ((strcmp(argv[i], "-I") == 0) - || (strcmp(argv[i], "--include") == 0)) - { + } else if (strcmp(argv[i], "-I") == 0 + || strcmp(argv[i], "--include") == 0) { if (i + 1 >= argc) - { error("%s should be followed by a directory name", argv[i]); - } - rdef_add_include_dir(argv[i + 1]); + rdef_add_include_dir(argv[i + 1], true); argv[i] = NULL; argv[i + 1] = NULL; ++i; args_left -= 2; - } - else if ((strcmp(argv[i], "-d") == 0) - || (strcmp(argv[i], "--decompile") == 0)) - { + } else if (strcmp(argv[i], "-d") == 0 + || strcmp(argv[i], "--decompile") == 0) { should_decompile = true; argv[i] = NULL; --args_left; - } - else if ((strcmp(argv[i], "-m") == 0) - || (strcmp(argv[i], "--merge") == 0)) - { + } else if (strcmp(argv[i], "-m") == 0 + || strcmp(argv[i], "--merge") == 0) { flags |= RDEF_MERGE_RESOURCES; argv[i] = NULL; --args_left; - } - else if (strcmp(argv[i], "--auto-names") == 0) - { + } else if (strcmp(argv[i], "--auto-names") == 0) { flags |= RDEF_AUTO_NAMES; argv[i] = NULL; --args_left; - } - else if ((strcmp(argv[i], "-q") == 0) - || (strcmp(argv[i], "--quiet") == 0)) - { + } else if (strcmp(argv[i], "-q") == 0 + || strcmp(argv[i], "--quiet") == 0) { quiet = true; argv[i] = NULL; --args_left; - } - else if ((strcmp(argv[i], "-h") == 0) - || (strcmp(argv[i], "--help") == 0)) - { + } else if (strcmp(argv[i], "-h") == 0 + || strcmp(argv[i], "--help") == 0) { usage(); - } - else if ((strcmp(argv[i], "-V") == 0) - || (strcmp(argv[i], "--version") == 0)) - { + } else if (strcmp(argv[i], "-V") == 0 + || strcmp(argv[i], "--version") == 0) { version(); - } - else if (argv[i][0] == '-') - { + } else if (argv[i][0] == '-') { error("unknown option %s", argv[i]); argv[i] = NULL; --args_left; @@ -221,78 +185,60 @@ static void parse_options(int argc, char* argv[]) } if (args_left < 1) - { error("no input files"); - } - for (int i = 1; i < argc; ++i) - { + for (int i = 1; i < argc; ++i) { if (argv[i] != NULL) - { rdef_add_input_file(argv[i]); - } } } -//------------------------------------------------------------------------------ -static bool has_extension(char* str, char* ext) +static bool +has_extension(char *str, char *ext) { size_t str_len = strlen(str); size_t ext_len = strlen(ext); if (str_len > ext_len) - { return (strcmp(str + str_len - ext_len, ext) == 0); - } return false; } -//------------------------------------------------------------------------------ -static void compile() +static void +compile() { - if (output_file[0] == '\0') - { + if (sOutputFile[0] == '\0') rdef_compile(DEFAULT_OUT_RSRC); - } - else - { - if (!has_extension(output_file, ".rsrc")) - { - strcat(output_file, ".rsrc"); - } + else { + if (!has_extension(sOutputFile, ".rsrc")) + strcat(sOutputFile, ".rsrc"); - rdef_compile(output_file); + rdef_compile(sOutputFile); } } -//------------------------------------------------------------------------------ -static void decompile() +static void +decompile() { - if (output_file[0] == '\0') - { + if (sOutputFile[0] == '\0') rdef_decompile(DEFAULT_OUT_RDEF); - } - else - { - if (!has_extension(output_file, ".rdef")) - { - strcat(output_file, ".rdef"); - } + else { + if (!has_extension(sOutputFile, ".rdef")) + strcat(sOutputFile, ".rdef"); - rdef_decompile(output_file); + rdef_decompile(sOutputFile); } } -//------------------------------------------------------------------------------ -static void report_error() +static void +report_error() { - switch (rdef_err) - { + switch (rdef_err) { case RDEF_COMPILE_ERR: error("%s:%ld %s", rdef_err_file, rdef_err_line, rdef_err_msg); break; @@ -320,35 +266,25 @@ static void report_error() } } -//------------------------------------------------------------------------------ -int main(int argc, char* argv[]) +int +main(int argc, char *argv[]) { - rdef_add_include_dir("."); // look in current dir first - - get_program_name(argv); parse_options(argc, argv); rdef_set_flags(flags); if (should_decompile) - { decompile(); - } else - { compile(); - } rdef_free_input_files(); rdef_free_include_dirs(); if (rdef_err != B_OK) - { report_error(); - } return EXIT_SUCCESS; } -//------------------------------------------------------------------------------ diff --git a/src/tools/rc/rdef.cpp b/src/tools/rc/rdef.cpp index 9d82fe1890..cdfcba7bf7 100644 --- a/src/tools/rc/rdef.cpp +++ b/src/tools/rc/rdef.cpp @@ -38,61 +38,87 @@ int32 rdef_err_line; char rdef_err_file[B_PATH_NAME_LENGTH]; char rdef_err_msg[1024]; -//------------------------------------------------------------------------------ -void free_ptr_list(ptr_list_t& list) +void +free_ptr_list(ptr_list_t &list) { - for (ptr_iter_t i = list.begin(); i != list.end(); ++i) - { + for (ptr_iter_t i = list.begin(); i != list.end(); ++i) { free(*i); } list.clear(); } -//------------------------------------------------------------------------------ -int32 rdef_get_version() +int32 +rdef_get_version() { return 2; } -//------------------------------------------------------------------------------ -status_t rdef_add_include_dir(const char* dir) +status_t +rdef_add_include_dir(const char *dir, bool toEndOfList) { clear_error(); - char* temp = (char*) malloc(strlen(dir) + 2); - if (temp == NULL) - { +printf("ADD: %s\n", dir); + char *path = (char *)malloc(strlen(dir) + 2); + if (path == NULL) { rdef_err = B_NO_MEMORY; return B_NO_MEMORY; } - strcpy(temp, dir); - strcat(temp, "/"); + strcpy(path, dir); + strcat(path, "/"); + + if (toEndOfList) + include_dirs.push_back(path); + else + include_dirs.push_front(path); - include_dirs.push_back(temp); return B_OK; } -//------------------------------------------------------------------------------ -void rdef_free_include_dirs() +status_t +rdef_remove_include_dir(const char *dir) +{ + size_t length = strlen(dir); + bool noSlash = false; + if (dir[length - 1] != '/') + noSlash = true; + + for (ptr_iter_t i = include_dirs.begin(); i != include_dirs.end(); ++i) { + char *path = (char *)*i; + + if (!strncmp(dir, path, length) + && path[length + (noSlash ? 1 : 0)] == '\0') { + // we found the entry in the list, let's remove it + include_dirs.erase(i); + free(path); + return B_OK; + } + } + + return B_ENTRY_NOT_FOUND; +} + + +void +rdef_free_include_dirs() { free_ptr_list(include_dirs); } -//------------------------------------------------------------------------------ -status_t rdef_add_input_file(const char* file) +status_t +rdef_add_input_file(const char *file) { clear_error(); - char* temp = strdup(file); - if (temp == NULL) - { + char *temp = strdup(file); + if (temp == NULL) { rdef_err = B_NO_MEMORY; return B_NO_MEMORY; } @@ -101,49 +127,47 @@ status_t rdef_add_input_file(const char* file) return B_OK; } -//------------------------------------------------------------------------------ -void rdef_free_input_files() +void +rdef_free_input_files() { free_ptr_list(input_files); } -//------------------------------------------------------------------------------ -void rdef_set_flags(uint32 flags_) +void +rdef_set_flags(uint32 flags_) { flags = flags_; } -//------------------------------------------------------------------------------ -void rdef_clear_flags() +void +rdef_clear_flags() { flags = 0; } -//------------------------------------------------------------------------------ -void clear_error() +void +clear_error() { - rdef_err = B_OK; - rdef_err_line = 0; + rdef_err = B_OK; + rdef_err_line = 0; rdef_err_file[0] = '\0'; - rdef_err_msg[0] = '\0'; + rdef_err_msg[0] = '\0'; } -//------------------------------------------------------------------------------ -bool open_file_from_include_dir(const char* filename, char* outname) +bool +open_file_from_include_dir(const char *filename, char *outname) { - for (ptr_iter_t i = include_dirs.begin(); i != include_dirs.end(); ++i) - { + for (ptr_iter_t i = include_dirs.begin(); i != include_dirs.end(); ++i) { char tmpname[B_PATH_NAME_LENGTH]; - strcpy(tmpname, (char*) *i); + strcpy(tmpname, (char *)*i); strcat(tmpname, filename); - if (access(tmpname, R_OK) == 0) - { + if (access(tmpname, R_OK) == 0) { strcpy(outname, tmpname); return true; } @@ -152,4 +176,3 @@ bool open_file_from_include_dir(const char* filename, char* outname) return false; } -//------------------------------------------------------------------------------ diff --git a/src/tools/rc/rdef.h b/src/tools/rc/rdef.h index 0bb43224b6..99f15bf025 100644 --- a/src/tools/rc/rdef.h +++ b/src/tools/rc/rdef.h @@ -66,8 +66,7 @@ extern "C" { #define RDEF_AUTO_NAMES (1 << 1) /** Error codes returned by the librdef functions. */ -enum -{ +enum { /** Syntax error or other compiler error. */ RDEF_COMPILE_ERR = B_ERRORS_END + 1, @@ -121,7 +120,10 @@ _IMPEXP_RDEF int32 rdef_get_version(); * Typically, you want to add the current directory to this list. * Not used for decompilation. */ -_IMPEXP_RDEF status_t rdef_add_include_dir(const char* dir); +_IMPEXP_RDEF status_t rdef_add_include_dir(const char *dir, bool toEndOfList); + +/** Removes an include directory */ +_IMPEXP_RDEF status_t rdef_remove_include_dir(const char *dir); /** * Frees the list of include directories. If you call rdef_add_include_dir(),