diff --git a/src/host/os_writefile_ifnotequal.c b/src/host/os_writefile_ifnotequal.c new file mode 100644 index 00000000..b0e0a7f3 --- /dev/null +++ b/src/host/os_writefile_ifnotequal.c @@ -0,0 +1,91 @@ +/** + * \file os_copyfile.c + * \brief Copy a file from one location to another. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include +#include +#include +#include "premake.h" + +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif + +static int compare_file(const char* content, size_t length, const char* dst) +{ + FILE* file = fopen(dst, "rb"); + long size; + char buffer[4096]; + int num; + + if (file == NULL) + { + return FALSE; + } + + // check sizes. + fseek(file, 0, SEEK_END); + size = ftell(file); + fseek(file, 0, SEEK_SET); + + if (length != size) + { + fclose(file); + return FALSE; + } + + while (size > 0) + { + num = size > 4096 ? 4096 : size; + + fread(buffer, 1, num, file); + + if (memcmp(content, buffer, num) != 0) + { + fclose(file); + return FALSE; + } + + size -= num; + content += num; + } + + fclose(file); + return TRUE; +} + + +int os_writefile_ifnotequal(lua_State* L) +{ + FILE* file; + size_t length; + const char* content = luaL_checklstring(L, 1, &length); + const char* dst = luaL_checkstring(L, 2); + + // if destination exist, and they are the same, no need to copy. + if (do_isfile(dst) && compare_file(content, length, dst)) + { + lua_pushinteger(L, 0); + return 1; + } + + + file = fopen(dst, "wb"); + if (file != NULL) + { + fwrite(content, 1, length, file); + fclose(file); + + lua_pushinteger(L, 1); + return 1; + } + + lua_pushinteger(L, -1); + lua_pushfstring(L, "unable to write file to '%s'", dst); + return 2; +} diff --git a/src/host/premake.c b/src/host/premake.c index bf18c42f..e6e131d3 100644 --- a/src/host/premake.c +++ b/src/host/premake.c @@ -53,27 +53,28 @@ static const luaL_Reg path_functions[] = { }; static const luaL_Reg os_functions[] = { - { "chdir", os_chdir }, - { "chmod", os_chmod }, - { "copyfile", os_copyfile }, - { "_is64bit", os_is64bit }, - { "isdir", os_isdir }, - { "getcwd", os_getcwd }, - { "getversion", os_getversion }, - { "isfile", os_isfile }, - { "islink", os_islink }, - { "locate", os_locate }, - { "matchdone", os_matchdone }, - { "matchisfile", os_matchisfile }, - { "matchname", os_matchname }, - { "matchnext", os_matchnext }, - { "matchstart", os_matchstart }, - { "mkdir", os_mkdir }, - { "pathsearch", os_pathsearch }, - { "realpath", os_realpath }, - { "rmdir", os_rmdir }, - { "stat", os_stat }, - { "uuid", os_uuid }, + { "chdir", os_chdir }, + { "chmod", os_chmod }, + { "copyfile", os_copyfile }, + { "_is64bit", os_is64bit }, + { "isdir", os_isdir }, + { "getcwd", os_getcwd }, + { "getversion", os_getversion }, + { "isfile", os_isfile }, + { "islink", os_islink }, + { "locate", os_locate }, + { "matchdone", os_matchdone }, + { "matchisfile", os_matchisfile }, + { "matchname", os_matchname }, + { "matchnext", os_matchnext }, + { "matchstart", os_matchstart }, + { "mkdir", os_mkdir }, + { "pathsearch", os_pathsearch }, + { "realpath", os_realpath }, + { "rmdir", os_rmdir }, + { "stat", os_stat }, + { "uuid", os_uuid }, + { "writefile_ifnotequal", os_writefile_ifnotequal }, { NULL, NULL } }; diff --git a/src/host/premake.h b/src/host/premake.h index f82b346d..08cebfb3 100644 --- a/src/host/premake.h +++ b/src/host/premake.h @@ -116,6 +116,7 @@ int os_realpath(lua_State* L); int os_rmdir(lua_State* L); int os_stat(lua_State* L); int os_uuid(lua_State* L); +int os_writefile_ifnotequal(lua_State* L); int string_endswith(lua_State* L); int string_hash(lua_State* L); int string_sha1(lua_State* L);