aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2017-12-30 04:32:49 +0100
committerdec05eba <dec05eba@protonmail.com>2017-12-30 05:08:10 +0100
commit98ad7dd049a366e21d60a34548736a3c8ef72877 (patch)
tree45e34eb02f6be9f9130a870a19ef1533e24bf343 /src
parent1f583ebb6e3973c992d59886659bf53ff87f41de (diff)
Add support for windows (ugly fast solution)
Diffstat (limited to 'src')
-rw-r--r--src/Archive.cpp38
-rw-r--r--src/Conf.cpp16
-rw-r--r--src/Exec.cpp49
-rw-r--r--src/FileUtil.cpp246
-rw-r--r--src/GlobalLib.cpp157
-rw-r--r--src/PkgConfig.cpp4
-rw-r--r--src/curl.cpp21
-rw-r--r--src/main.cpp160
8 files changed, 502 insertions, 189 deletions
diff --git a/src/Archive.cpp b/src/Archive.cpp
index 08ab42b..506b020 100644
--- a/src/Archive.cpp
+++ b/src/Archive.cpp
@@ -6,6 +6,14 @@
using namespace std;
+#if OS_FAMILY == OS_FAMILY_POSIX
+#define archive_read_open_filename_native archive_read_open_filename
+#define archive_entry_pathname_native archive_entry_pathname
+#else
+#define archive_read_open_filename_native archive_read_open_filename_w
+#define archive_entry_pathname_native archive_entry_pathname_w
+#endif
+
class FileHandler
{
DISABLE_COPY(FileHandler)
@@ -53,7 +61,7 @@ namespace sibs
}
}
- Result<bool> Archive::extract(const char *source, const char *destination)
+ Result<bool> Archive::extract(const _tinydir_char_t *source, const _tinydir_char_t *destination)
{
struct archive *a;
struct archive *ext;
@@ -67,7 +75,7 @@ namespace sibs
flags |= ARCHIVE_EXTRACT_ACL;
flags |= ARCHIVE_EXTRACT_FFLAGS;
- string rootName;
+ FileString rootName;
a = archive_read_new();
archive_read_support_format_all(a);
@@ -77,10 +85,10 @@ namespace sibs
archive_write_disk_set_standard_lookup(ext);
- if ((r = archive_read_open_filename(a, source, 10240)))
+ if ((r = archive_read_open_filename_native(a, source, 10240)))
{
string errMsg = "Failed to extract archive: ";
- errMsg += source;
+ errMsg += toUtf8(source);
return Result<bool>::Err(errMsg);
}
@@ -92,7 +100,7 @@ namespace sibs
else if (r < ARCHIVE_OK)
{
string errMsg = "Failed to extract archive: ";
- errMsg += source;
+ errMsg += toUtf8(source);
errMsg += "; reason: ";
errMsg += archive_error_string(a);
return Result<bool>::Err(errMsg);
@@ -100,25 +108,27 @@ namespace sibs
else if (r < ARCHIVE_WARN)
{
string errMsg = "Failed to extract archive: ";
- errMsg += source;
+ errMsg += toUtf8(source);
errMsg += "; reason: ";
errMsg += archive_error_string(a);
return Result<bool>::Err(errMsg);
}
- const char* currentFile = archive_entry_pathname(entry);
+ const _tinydir_char_t* currentFile = archive_entry_pathname_native(entry);
if(rootName.empty())
rootName = currentFile;
- std::string fullOutputPath = destination;
+ FileString fullOutputPath = destination;
fullOutputPath += (currentFile + (rootName.empty() ? 0 : rootName.size() - 1));
- archive_entry_set_pathname(entry, fullOutputPath.c_str());
+ // TODO: Verify if this really works. Why doesn't libarchive have wide string version of archive_entry_set_pathname?
+ string fullOutputPathUtf8 = toUtf8(fullOutputPath);
+ archive_entry_set_pathname(entry, fullOutputPathUtf8.c_str());
r = archive_write_header(ext, entry);
if (r < ARCHIVE_OK)
{
string errMsg = "Failed to extract archive: ";
- errMsg += source;
+ errMsg += toUtf8(source);
errMsg += "; reason: ";
errMsg += archive_error_string(ext);
return Result<bool>::Err(errMsg);
@@ -128,7 +138,7 @@ namespace sibs
if (r < ARCHIVE_OK)
{
string errMsg = "Failed to extract archive: ";
- errMsg += source;
+ errMsg += toUtf8(source);
errMsg += "; reason: ";
errMsg += archive_error_string(ext);
return Result<bool>::Err(errMsg);
@@ -136,7 +146,7 @@ namespace sibs
else if (r < ARCHIVE_WARN)
{
string errMsg = "Failed to extract archive: ";
- errMsg += source;
+ errMsg += toUtf8(source);
errMsg += "; reason: ";
errMsg += archive_error_string(ext);
return Result<bool>::Err(errMsg);
@@ -147,7 +157,7 @@ namespace sibs
if (r < ARCHIVE_OK)
{
string errMsg = "Failed to extract archive: ";
- errMsg += source;
+ errMsg += toUtf8(source);
errMsg += "; reason: ";
errMsg += archive_error_string(ext);
return Result<bool>::Err(errMsg);
@@ -155,7 +165,7 @@ namespace sibs
else if (r < ARCHIVE_WARN)
{
string errMsg = "Failed to extract archive: ";
- errMsg += source;
+ errMsg += toUtf8(source);
errMsg += "; reason: ";
errMsg += archive_error_string(ext);
return Result<bool>::Err(errMsg);
diff --git a/src/Conf.cpp b/src/Conf.cpp
index d6aee2c..743942a 100644
--- a/src/Conf.cpp
+++ b/src/Conf.cpp
@@ -1,5 +1,5 @@
#include "../include/Conf.hpp"
-#include "../include/FileUtil.hpp"
+#include "../include/types.hpp"
#include "../external/utf8/unchecked.h"
using namespace std;
@@ -7,8 +7,6 @@ using u8string = utf8::unchecked::iterator<char*>;
namespace sibs
{
- u32 min(u32 a, u32 b) { return a < b ? a : b; }
-
class UnexpectedTokenException : public std::runtime_error
{
public:
@@ -316,7 +314,7 @@ namespace sibs
bool objectDefined;
};
- Result<bool> Config::readFromFile(const char *filepath, const ConfigCallback &callback)
+ Result<bool> Config::readFromFile(const _tinydir_char_t *filepath, const ConfigCallback &callback)
{
Result<StringView> fileContentResult = getFileContent(filepath);
if(fileContentResult.isErr())
@@ -409,9 +407,13 @@ namespace sibs
if (value.isSingle())
{
testPath = projectPath;
- testPath += "/";
- testPath += string(value.asSingle().data, value.asSingle().size);
- Result<string> testRealPathResult = getRealPath(testPath.c_str());
+ testPath += TINYDIR_STRING("/");
+#if OS_FAMILY == OS_FAMILY_POSIX
+ testPath += FileString(value.asSingle().data, value.asSingle().size);
+#else
+ testPath += utf8To16(value.asSingle());
+#endif
+ Result<FileString> testRealPathResult = getRealPath(testPath.c_str());
if(!testRealPathResult)
{
string errMsg = "Failed to resolve package.tests path: ";
diff --git a/src/Exec.cpp b/src/Exec.cpp
index 37ffef5..e0ae306 100644
--- a/src/Exec.cpp
+++ b/src/Exec.cpp
@@ -1,10 +1,12 @@
#include "../include/Exec.hpp"
+#include "../include/env.hpp"
using namespace std;
namespace sibs
{
- Result<ExecResult> exec(const char *cmd, bool print)
+#if OS_FAMILY == OS_FAMILY_POSIX
+ Result<ExecResult> exec(const _tinydir_char_t *cmd, bool print)
{
char buffer[128];
std::string result;
@@ -52,4 +54,49 @@ namespace sibs
return Result<ExecResult>::Err(errMsg);
}
}
+#else
+ // TODO(Windows): Redirect stdout (and stderr) to string
+ Result<ExecResult> exec(const _tinydir_char_t *cmd, bool print)
+ {
+ char buffer[128];
+ std::string result;
+
+ STARTUPINFO startupInfo;
+ ZeroMemory(&startupInfo, sizeof(startupInfo));
+ startupInfo.cb = sizeof(startupInfo);
+
+ PROCESS_INFORMATION processInfo;
+ ZeroMemory(&processInfo, sizeof(processInfo));
+
+ DWORD exitCode;
+
+ if (!CreateProcess(NULL, (LPWSTR)cmd, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInfo))
+ {
+ string errMsg = "exec unexpected error: ";
+ errMsg += toUtf8(getLastErrorAsString());
+ return Result<ExecResult>::Err(errMsg);
+ }
+
+ WaitForSingleObject(processInfo.hProcess, INFINITE);
+ GetExitCodeProcess(processInfo.hProcess, &exitCode);
+ CloseHandle(processInfo.hProcess);
+ CloseHandle(processInfo.hThread);
+
+ if (exitCode == 0)
+ {
+ ExecResult execResult;
+ execResult.execStdout = result;
+ execResult.exitCode = exitCode;
+ return Result<ExecResult>::Ok(execResult);
+ }
+ else
+ {
+ string errMsg = "Exited with non-zero exit code (";
+ errMsg += to_string(exitCode);
+ errMsg += "): ";
+ errMsg += toUtf8(getLastErrorAsString());
+ return Result<ExecResult>::Err(errMsg);
+ }
+ }
+#endif
} \ No newline at end of file
diff --git a/src/FileUtil.cpp b/src/FileUtil.cpp
index d075f2b..5cf8377 100644
--- a/src/FileUtil.cpp
+++ b/src/FileUtil.cpp
@@ -1,5 +1,4 @@
#include "../include/FileUtil.hpp"
-#include "../include/env.hpp"
#include <cstdio>
#if OS_FAMILY == OS_FAMILY_POSIX
@@ -7,27 +6,92 @@
#include <sys/types.h>
#include <pwd.h>
#include <fcntl.h>
+#else
+#include <UserEnv.h>
+// Copied from linux libc sys/stat.h:
+#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif
using namespace std;
namespace sibs
{
- FileType getFileType(const char *path)
+#if OS_FAMILY == OS_FAMILY_POSIX
+#define toUtf8(input) input
+ FileString toFileString(const std::string &utf8Str)
{
- tinydir_file file;
- if(tinydir_file_open(&file, path) == 0)
- {
- return file.is_dir ? FileType::DIRECTORY : FileType::REGULAR;
- }
+ return utf8Str;
+ }
+#else
+ std::string toUtf8(const sibs::FileString &input)
+ {
+ std::string result;
+ utf8::utf16to8(input.data(), input.data() + input.size(), std::back_inserter(result));
+ return result;
+ }
+
+ std::string toUtf8(const TCHAR *input)
+ {
+ size_t inputSize = wcslen(input);
+ std::string result;
+ utf8::utf16to8(input, input + inputSize, std::back_inserter(result));
+ return result;
+ }
+
+ FileString utf8To16(const StringView &utf8Str)
+ {
+ FileString result;
+ utf8::utf8to16(utf8Str.data, utf8Str.data + utf8Str.size, std::back_inserter(result));
+ return result;
+ }
+
+ FileString utf8To16(const std::string &utf8Str)
+ {
+ FileString result;
+ utf8::utf8to16(utf8Str.data(), utf8Str.data() + utf8Str.size(), std::back_inserter(result));
+ return result;
+ }
+
+ FileString toFileString(const std::string &utf8Str)
+ {
+ return utf8To16(utf8Str);
+ }
+
+ FileString getLastErrorAsString()
+ {
+ DWORD errorMessageId = GetLastError();
+ if (errorMessageId == 0) return TINYDIR_STRING("");
+ LPWSTR messageBuffer = nullptr;
+ size_t size = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, errorMessageId, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&messageBuffer, 0, nullptr);
+ FileString message(messageBuffer, size);
+ LocalFree(messageBuffer);
+ return message;
+ }
+#endif
+
+#if OS_FAMILY == OS_FAMILY_POSIX
+ FileType getFileType(const _tinydir_char_t *path)
+ {
+ struct stat64 fileStat;
+ if (stat64(path, &fileStat) == 0)
+ return S_ISREG(fileStat.st_mode) ? FileType::REGULAR : FileType::DIRECTORY;
else
- {
return FileType::FILE_NOT_FOUND;
- }
}
+#else
+ FileType getFileType(const _tinydir_char_t *path)
+ {
+ struct _stat64i32 fileStat;
+ if (_wstat(path, &fileStat) == 0)
+ return S_ISREG(fileStat.st_mode) ? FileType::REGULAR : FileType::DIRECTORY;
+ else
+ return FileType::FILE_NOT_FOUND;
+ }
+#endif
// TODO: Handle failure (directory doesn't exist, no permission etc)
- void walkDir(const char *directory, FileWalkCallbackFunc callbackFunc)
+ void walkDir(const _tinydir_char_t *directory, FileWalkCallbackFunc callbackFunc)
{
tinydir_dir dir;
tinydir_open(&dir, directory);
@@ -36,7 +100,7 @@ namespace sibs
{
tinydir_file file;
tinydir_readfile(&dir, &file);
- if(_tinydir_strcmp(file.name, ".") != 0 && _tinydir_strcmp(file.name, "..") != 0)
+ if(_tinydir_strcmp(file.name, TINYDIR_STRING(".")) != 0 && _tinydir_strcmp(file.name, TINYDIR_STRING("..")) != 0)
callbackFunc(&file);
tinydir_next(&dir);
}
@@ -45,7 +109,7 @@ namespace sibs
}
// TODO: Handle failure (directory doesn't exist, no permission etc)
- void walkDirFiles(const char *directory, FileWalkCallbackFunc callbackFunc)
+ void walkDirFiles(const _tinydir_char_t *directory, FileWalkCallbackFunc callbackFunc)
{
tinydir_dir dir;
tinydir_open(&dir, directory);
@@ -63,7 +127,7 @@ namespace sibs
}
// TODO: Handle failure (directory doesn't exist, no permission etc)
- void walkDirFilesRecursive(const char *directory, FileWalkCallbackFunc callbackFunc)
+ void walkDirFilesRecursive(const _tinydir_char_t *directory, FileWalkCallbackFunc callbackFunc)
{
tinydir_dir dir;
tinydir_open(&dir, directory);
@@ -74,7 +138,7 @@ namespace sibs
tinydir_readfile(&dir, &file);
if(file.is_reg)
callbackFunc(&file);
- else if(_tinydir_strcmp(file.name, ".") != 0 && _tinydir_strcmp(file.name, "..") != 0)
+ else if(_tinydir_strcmp(file.name, TINYDIR_STRING(".")) != 0 && _tinydir_strcmp(file.name, TINYDIR_STRING("..")) != 0)
walkDirFilesRecursive(file.path, callbackFunc);
tinydir_next(&dir);
}
@@ -82,14 +146,18 @@ namespace sibs
tinydir_close(&dir);
}
- Result<StringView> getFileContent(const char *filepath)
+ Result<StringView> getFileContent(const _tinydir_char_t *filepath)
{
+#if OS_FAMILY == OS_FAMILY_POSIX
FILE *file = fopen(filepath, "rb");
+#else
+ FILE *file = _wfopen(filepath, TINYDIR_STRING("rb"));
+#endif
if(!file)
{
int error = errno;
string errMsg = "Failed to open file: ";
- errMsg += filepath;
+ errMsg += toUtf8(filepath);
errMsg += "; reason: ";
errMsg += strerror(error);
return Result<StringView>::Err(errMsg);
@@ -104,7 +172,7 @@ namespace sibs
if(!result)
{
std::string errMsg = "Failed to load file content from file: ";
- errMsg += filepath;
+ errMsg += toUtf8(filepath);
throw std::runtime_error(errMsg);
}
result[fileSize] = '\0';
@@ -113,14 +181,18 @@ namespace sibs
return Result<StringView>::Ok(StringView(result, fileSize));
}
- Result<bool> fileOverwrite(const char *filepath, StringView data)
+ Result<bool> fileOverwrite(const _tinydir_char_t *filepath, StringView data)
{
+#if OS_FAMILY == OS_FAMILY_POSIX
FILE *file = fopen(filepath, "wb");
+#else
+ FILE *file = _wfopen(filepath, TINYDIR_STRING("wb"));
+#endif
if(!file)
{
int error = errno;
string errMsg = "Failed to overwrite file: ";
- errMsg += filepath;
+ errMsg += toUtf8(filepath);
errMsg += "; reason: ";
errMsg += strerror(error);
return Result<bool>::Err(errMsg);
@@ -130,8 +202,8 @@ namespace sibs
fclose(file);
return Result<bool>::Ok(true);
}
-
- const char* getHomeDir()
+#if OS_FAMILY == OS_FAMILY_POSIX
+ Result<FileString> getHomeDir()
{
const char *homeDir = getenv("HOME");
if(!homeDir)
@@ -139,26 +211,25 @@ namespace sibs
passwd *pw = getpwuid(getuid());
homeDir = pw->pw_dir;
}
- return homeDir;
+ return Result<FileString>::Ok(homeDir);
}
- Result<string> getCwd()
+ Result<FileString> getCwd()
{
- string cwd;
- cwd.reserve(PATH_MAX);
- if(getcwd(&cwd[0], PATH_MAX) != 0)
+ FileString cwd;
+ cwd.resize(_TINYDIR_PATH_MAX);
+ if(getcwd(&cwd[0], _TINYDIR_PATH_MAX) != 0)
{
if(cwd.empty()) cwd = ".";
- return Result<string>::Ok(cwd);
+ cwd.resize(_tinydir_strlen(cwd.c_str()));
+ return Result<FileString>::Ok(cwd);
}
-
- return Result<string>::Err(strerror(errno));
+ return Result<FileString>::Err(strerror(errno));
}
-#if OS_FAMILY == OS_FAMILY_POSIX
- Result<bool> createDirectoryRecursive(const char *path)
+ Result<bool> createDirectoryRecursive(const _tinydir_char_t *path)
{
- char pathBuffer[PATH_MAX];
+ char pathBuffer[_TINYDIR_PATH_MAX];
size_t pathLength = strlen(path);
if(pathLength > sizeof(pathBuffer) - 1)
{
@@ -207,25 +278,126 @@ namespace sibs
return Result<bool>::Ok(true);
}
- Result<string> getRealPath(const char *path)
+ Result<FileString> getRealPath(const _tinydir_char_t *path)
{
// TODO: Verify NULL can be passed as 'resolved' argument with different compilers and operating systems (clang, freebsd etc)
char *resolved = realpath(path, nullptr);
if(!resolved)
{
int error = errno;
- string errMsg = "Failed to get real path for \"";
+ FileString errMsg = "Failed to get real path for \"";
errMsg += path;
errMsg += "\": ";
errMsg += strerror(error);
- return Result<string>::Err(errMsg, error);
+ return Result<FileString>::Err(errMsg, error);
}
string result = resolved;
free(resolved);
- return Result<string>::Ok(result);
+ return Result<FileString>::Ok(result);
}
#else
-#error "TODO: Implement createDirectoryRecursive and getRealPath on windows"
+
+#pragma comment(lib, "Userenv.lib")
+
+ Result<FileString> getHomeDir()
+ {
+ BOOL ret;
+ HANDLE hToken;
+ FileString homeDir;
+ DWORD homeDirLen = _TINYDIR_PATH_MAX;
+ homeDir.resize(homeDirLen);
+
+ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &hToken))
+ return Result<FileString>::Err("Failed to open process token");
+
+ if (!GetUserProfileDirectory(hToken, &homeDir[0], &homeDirLen))
+ return Result<FileString>::Err("Failed to get home directory");
+
+ CloseHandle(hToken);
+ homeDir.resize(_tinydir_strlen(homeDir.c_str()));
+ return Result<FileString>::Ok(homeDir);
+ }
+
+ Result<FileString> getCwd()
+ {
+ FileString cwd;
+ cwd.resize(_TINYDIR_PATH_MAX);
+ if (GetCurrentDirectory(_TINYDIR_PATH_MAX, &cwd[0]) == 0)
+ {
+ FileString lastErrStr = getLastErrorAsString();
+ return Result<FileString>::Err(toUtf8(lastErrStr));
+ }
+ cwd.resize(_tinydir_strlen(cwd.c_str()));
+ return Result<FileString>::Ok(cwd);
+ }
+
+ Result<bool> createDirectoryRecursive(const _tinydir_char_t *path)
+ {
+ _tinydir_char_t pathBuffer[_TINYDIR_PATH_MAX];
+ size_t pathLength = _tinydir_strlen(path);
+ if (pathLength > sizeof(pathBuffer) - 1)
+ {
+ string errMsg = "Directory path too long: ";
+ errMsg += toUtf8(FileString(path, pathLength));
+ return Result<bool>::Err(errMsg, ENAMETOOLONG);
+ }
+ _tinydir_strcpy(pathBuffer, path);
+
+ _tinydir_char_t *p = pathBuffer;
+ for (size_t i = 0; i < pathLength; ++i)
+ {
+ if (i > 0 && *p == '/')
+ {
+ *p = '\0';
+ if (_wmkdir(pathBuffer) != 0)
+ {
+ int error = errno;
+ if (error != EEXIST)
+ {
+ string errMsg = "Failed to create directory: ";
+ errMsg += toUtf8(pathBuffer);
+ errMsg += "; reason: ";
+ errMsg += strerror(error);
+ return Result<bool>::Err(errMsg, error);
+ }
+ }
+ *p = '/';
+ }
+ ++p;
+ }
+
+ if (_wmkdir(pathBuffer) != 0)
+ {
+ int error = errno;
+ if (error != EEXIST)
+ {
+ string errMsg = "Failed to create directory: ";
+ errMsg += toUtf8(pathBuffer);
+ errMsg += "; reason: ";
+ errMsg += strerror(error);
+ return Result<bool>::Err(errMsg, error);
+ }
+ }
+
+ return Result<bool>::Ok(true);
+ }
+
+ Result<FileString> getRealPath(const _tinydir_char_t *path)
+ {
+ FileString fullPath;
+ fullPath.resize(_TINYDIR_PATH_MAX);
+ if (GetFullPathName(path, _TINYDIR_PATH_MAX, &fullPath[0], nullptr) == 0)
+ {
+ int error = GetLastError();
+ string errMsg = "Failed to get real path for \"";
+ errMsg += toUtf8(path);
+ errMsg += "\": ";
+ errMsg += toUtf8(getLastErrorAsString());
+ return Result<FileString>::Err(errMsg, error);
+ }
+ fullPath.resize(_tinydir_strlen(fullPath.c_str()));
+ return Result<FileString>::Ok(fullPath);
+ }
#endif
} \ No newline at end of file
diff --git a/src/GlobalLib.cpp b/src/GlobalLib.cpp
index d994a27..db85abd 100644
--- a/src/GlobalLib.cpp
+++ b/src/GlobalLib.cpp
@@ -9,23 +9,27 @@ using namespace std;
namespace sibs
{
- Result<bool> GlobalLib::validatePackageExists(const string &globalLibRootDir, const string &name)
+ Result<bool> GlobalLib::validatePackageExists(const FileString &globalLibRootDir, const std::string &name)
{
- string packageDir = globalLibRootDir + "/";
+ FileString packageDir = globalLibRootDir + TINYDIR_STRING("/");
+#if OS_FAMILY == OS_FAMILY_POSIX
packageDir += name;
+#else
+ packageDir += utf8To16(name);
+#endif
FileType packageDirFileType = getFileType(packageDir.c_str());
switch(packageDirFileType)
{
case FileType::FILE_NOT_FOUND:
{
string errMsg = "Global lib dependency not found: ";
- errMsg += name;
+ errMsg += toUtf8(packageDir);
return Result<bool>::Err(errMsg, DependencyError::DEPENDENCY_NOT_FOUND);
}
case FileType::REGULAR:
{
string errMsg = "Corrupt library directory. ";
- errMsg += packageDir;
+ errMsg += toUtf8(packageDir);
errMsg += " is a file, expected it to be a directory";
return Result<bool>::Err(errMsg);
}
@@ -40,13 +44,13 @@ namespace sibs
}
}
- const char *sourceFileExtensions[] = { "c", "cc", "cpp", "cxx" };
+ const _tinydir_char_t *sourceFileExtensions[] = { TINYDIR_STRING("c"),TINYDIR_STRING("cc"), TINYDIR_STRING("cpp"), TINYDIR_STRING("cxx") };
bool isSourceFile(tinydir_file *file)
{
if(!file->is_reg)
return false;
- for(const char *sourceFileExtension : sourceFileExtensions)
+ for(const _tinydir_char_t *sourceFileExtension : sourceFileExtensions)
{
if(_tinydir_strcmp(sourceFileExtension, file->extension) == 0)
return true;
@@ -55,29 +59,37 @@ namespace sibs
return false;
}
- bool isPathSubPathOf(const char *path, const string &subPathOf)
+ bool isPathSubPathOf(const _tinydir_char_t *path, const FileString &subPathOf)
{
return _tinydir_strncmp(path, subPathOf.c_str(), subPathOf.size()) == 0;
}
- Result<string> GlobalLib::getLibsLinkerFlags(const SibsConfig &parentConfig, const string &globalLibRootDir, const string &name, const string &version, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallbackFunc)
+ Result<string> GlobalLib::getLibsLinkerFlags(const SibsConfig &parentConfig, const FileString &globalLibRootDir, const std::string &name, const std::string &version, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallbackFunc)
{
Result<bool> packageExistsResult = validatePackageExists(globalLibRootDir, name);
if(packageExistsResult.isErr())
return Result<string>::Err(packageExistsResult);
- string packageDir = globalLibRootDir + "/";
- packageDir += name;
+#if OS_FAMILY == OS_FAMILY_POSIX
+ FileString namePlatformNative = name;
+ FileString versionPlatformNative = version;
+#else
+ FileString namePlatformNative = utf8To16(name);
+ FileString versionPlatformNative = utf8To16(version);
+#endif
+
+ FileString packageDir = globalLibRootDir + TINYDIR_STRING("/");
+ packageDir += namePlatformNative;
// TODO: Instead of checking if version is exact match, check if package has same major version
// and same or newer minor version
- string foundVersion;
- walkDir(packageDir.c_str(), [&foundVersion, &version](tinydir_file *file)
+ FileString foundVersion;
+ walkDir(packageDir.c_str(), [&foundVersion, &versionPlatformNative](tinydir_file *file)
{
if(file->is_dir)
{
//printf("version: %s\n", file->name);
- if(_tinydir_strcmp(version.c_str(), file->name) == 0)
+ if(_tinydir_strcmp(versionPlatformNative.c_str(), file->name) == 0)
foundVersion = file->name;
}
});
@@ -85,11 +97,11 @@ namespace sibs
if(foundVersion.empty())
return Result<string>::Err("Global lib dependency found, but version doesn't match dependency version", DependencyError::DEPENDENCY_VERSION_NO_MATCH);
- packageDir += "/";
- packageDir += version;
+ packageDir += TINYDIR_STRING("/");
+ packageDir += versionPlatformNative;
- string projectConfFilePath = packageDir;
- projectConfFilePath += "/project.conf";
+ FileString projectConfFilePath = packageDir;
+ projectConfFilePath += TINYDIR_STRING("/project.conf");
FileType projectConfFileType = getFileType(projectConfFilePath.c_str());
switch(projectConfFileType)
@@ -97,20 +109,20 @@ namespace sibs
case FileType::FILE_NOT_FOUND:
{
string errMsg = "Global lib dependency found: ";
- errMsg += packageDir;
+ errMsg += toUtf8(packageDir);
errMsg += ", but it's missing a project.conf file";
return Result<string>::Err(errMsg);
}
case FileType::DIRECTORY:
{
string errMsg = "Global lib dependency found: ";
- errMsg += packageDir;
+ errMsg += toUtf8(packageDir);
errMsg += ", but it's corrupt (Found directory instead of file)";
return Result<string>::Err(errMsg);
}
}
- SibsConfig sibsConfig(packageDir, parentConfig.getOptimizationLevel());
+ SibsConfig sibsConfig(parentConfig.getCompiler(), packageDir, parentConfig.getOptimizationLevel());
Result<bool> result = Config::readFromFile(projectConfFilePath.c_str(), sibsConfig);
if(result.isErr())
return Result<string>::Err(result.getErrMsg());
@@ -148,7 +160,8 @@ namespace sibs
{
if (isSourceFile(file))
{
- ninja.addSourceFile(file->path + sibsConfig.getProjectPath().size() + 1);
+ string fileNameNative = toUtf8(file->path + sibsConfig.getProjectPath().size() + 1);
+ ninja.addSourceFile(fileNameNative.c_str());
}
else
{
@@ -160,8 +173,11 @@ namespace sibs
// TODO: If compiling without "test" option, do not add test source dir to ninja. Ninja logic will then not build tests...
// OR I believe there is no reason to run tests in dependencies. The main projects tests should cover that?
// But you might want to know exactly which dependency is causing issue and which part of it...
- if(!sibsConfig.getTestPath().empty() && isPathSubPathOf(file->path, sibsConfig.getTestPath()))
- ninja.addTestSourceDir(file->path);
+ if (!sibsConfig.getTestPath().empty() && isPathSubPathOf(file->path, sibsConfig.getTestPath()))
+ {
+ string filePathUtf8 = toUtf8(file->path);
+ ninja.addTestSourceDir(filePathUtf8.c_str());
+ }
else
walkDir(file->path, collectSourceFiles);
}
@@ -175,36 +191,64 @@ namespace sibs
}
else
{
- string buildPath = packageDir + "/sibs-build/";
+ FileString buildPath = packageDir + TINYDIR_STRING("/sibs-build/");
switch(sibsConfig.getOptimizationLevel())
{
case OPT_LEV_DEBUG:
- buildPath += "debug";
+ buildPath += TINYDIR_STRING("debug");
break;
case OPT_LEV_RELEASE:
- buildPath += "release";
+ buildPath += TINYDIR_STRING("release");
break;
}
-
- string libPath = buildPath;
- libPath += "/lib";
- libPath += name;
- if(libraryType == backend::Ninja::LibraryType::STATIC)
- {
- libPath += ".a";
- string libPathCmd = "'";
- libPathCmd += libPath;
- libPathCmd += "'";
- staticLinkerFlagCallbackFunc(libPathCmd);
- libPath += ".a";
- }
- else
+
+ string libPath = toUtf8(buildPath);
+ switch (sibsConfig.getCompiler())
{
- libPath += ".so";
- string libPathCmd = "'";
- libPathCmd += libPath;
- libPathCmd += "'";
- dynamicLinkerFlagCallbackFunc(libPathCmd);
+ case Compiler::GCC:
+ {
+ libPath += "/lib";
+ libPath += name;
+ if (libraryType == backend::Ninja::LibraryType::STATIC)
+ {
+ libPath += ".a";
+ string libPathCmd = "'";
+ libPathCmd += libPath;
+ libPathCmd += "'";
+ staticLinkerFlagCallbackFunc(libPathCmd);
+ }
+ else
+ {
+ libPath += ".so";
+ string libPathCmd = "'";
+ libPathCmd += libPath;
+ libPathCmd += "'";
+ dynamicLinkerFlagCallbackFunc(libPathCmd);
+ }
+ break;
+ }
+ case Compiler::MSVC:
+ {
+ libPath += "/";
+ libPath += name;
+ if (libraryType == backend::Ninja::LibraryType::STATIC)
+ {
+ libPath += ".lib";
+ string libPathCmd = "\"";
+ libPathCmd += libPath;
+ libPathCmd += "\"";
+ staticLinkerFlagCallbackFunc(libPathCmd);
+ }
+ else
+ {
+ libPath += ".lib";
+ string libPathCmd = "\"";
+ libPathCmd += libPath;
+ libPathCmd += "\"";
+ dynamicLinkerFlagCallbackFunc(libPathCmd);
+ }
+ break;
+ }
}
// TODO: Use different directories depending on the project type, but .o build files should be in the same directory
@@ -229,21 +273,24 @@ namespace sibs
url += dependency.version;
url += ".tar.gz";
- string libPath = getHomeDir();
- libPath += "/.sibs/lib/";
- libPath += dependency.name;
- libPath += "/";
- libPath += dependency.version;
+ Result<FileString> libPathResult = getHomeDir();
+ if (!libPathResult)
+ return Result<bool>::Err(libPathResult);
+ FileString libPath = libPathResult.unwrap();
+ libPath += TINYDIR_STRING("/.sibs/lib/");
+ libPath += toFileString(dependency.name);
+ libPath += TINYDIR_STRING("/");
+ libPath += toFileString(dependency.version);
- string libArchivedFilePath = getHomeDir();
- libArchivedFilePath += "/.sibs/archive/";
- libArchivedFilePath += dependency.name;
+ FileString libArchivedFilePath = libPathResult.unwrap();
+ libArchivedFilePath += TINYDIR_STRING("/.sibs/archive/");
+ libArchivedFilePath += toFileString(dependency.name);
Result<bool> createArchiveDirResult = createDirectoryRecursive(libArchivedFilePath.c_str());
if(createArchiveDirResult.isErr())
return createArchiveDirResult;
- libArchivedFilePath += "/";
- libArchivedFilePath += dependency.version;
+ libArchivedFilePath += TINYDIR_STRING("/");
+ libArchivedFilePath += toFileString(dependency.version);
Result<bool> downloadResult = curl::downloadFile(url.c_str(), libArchivedFilePath.c_str());
if(downloadResult.isErr())
return downloadResult;
diff --git a/src/PkgConfig.cpp b/src/PkgConfig.cpp
index 620b1a7..a66d5b3 100644
--- a/src/PkgConfig.cpp
+++ b/src/PkgConfig.cpp
@@ -1,4 +1,5 @@
#include "../include/PkgConfig.hpp"
+#if OS_FAMILY == OS_FAMILY_POSIX
#include "../include/Exec.hpp"
using namespace std;
@@ -127,4 +128,5 @@ namespace sibs
return Result<string>::Err(errMsg);
}
}
-} \ No newline at end of file
+}
+#endif // OS_FAMILY_POSIX
diff --git a/src/curl.cpp b/src/curl.cpp
index 56c19ec..a3c5e28 100644
--- a/src/curl.cpp
+++ b/src/curl.cpp
@@ -5,6 +5,12 @@
using namespace std;
+#if OS_FAMILY == OS_FAMILY_WINDOWS
+#pragma comment(lib, "Ws2_32.lib")
+#pragma comment(lib, "Wldap32.lib")
+#pragma comment(lib, "Crypt32.lib")
+#endif
+
#ifdef DEBUG
#define CURL_DEBUG
#endif
@@ -44,7 +50,7 @@ namespace sibs
return size * nmemb;
}
- Result<bool> curl::downloadFile(const char *url, const char *filepath)
+ Result<bool> curl::downloadFile(const char *url, const _tinydir_char_t *filepath)
{
CURL *curl_handle = curl_easy_init();
curl_easy_setopt(curl_handle, CURLOPT_URL, url);
@@ -60,15 +66,19 @@ namespace sibs
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, writeToFile);
curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, true);
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "SIBS");
-
+ curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, FALSE);
+#if OS_FAMILY == OS_FAMILY_POSIX
FILE *file = fopen(filepath, "wb");
+#else
+ FILE *file = _wfopen(filepath, L"wb");
+#endif
if(!file)
{
int error = errno;
curl_easy_cleanup(curl_handle);
string errMsg = "Failed to open file for writing: ";
- errMsg += filepath;
+ errMsg += toUtf8(filepath);
if(error != 0)
{
errMsg += "; Reason: ";
@@ -131,8 +141,9 @@ namespace sibs
curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, noProgressMeter);
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, writeToString);
curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, true);
- curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "Hacker");
-
+ curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "SIBS");
+ curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, FALSE);
+
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, &result.str);
printf("Downloading from url: %s\n", url);
CURLcode curlResponse = curl_easy_perform(curl_handle);
diff --git a/src/main.cpp b/src/main.cpp
index 0f20ea0..f49ba59 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -20,6 +20,12 @@ using namespace sibs;
// TODO: Places that use PATH_MAX should be modified. A path CAN be longer than PATH_MAX... (does this include replacing tinydir.h?)
+#if OS_FAMILY == OS_FAMILY_POSIX
+#define ferr std::cerr
+#else
+#define ferr std::wcerr
+#endif
+
void usage()
{
printf("Usage: sibs COMMAND\n\n");
@@ -59,47 +65,47 @@ void usageNew()
exit(1);
}
-void validateDirectoryPath(const char *projectPath)
+void validateDirectoryPath(const _tinydir_char_t *projectPath)
{
FileType projectPathFileType = getFileType(projectPath);
if(projectPathFileType == FileType::FILE_NOT_FOUND)
{
string errMsg = "Invalid project path: ";
- errMsg += projectPath;
+ errMsg += toUtf8(projectPath);
perror(errMsg.c_str());
exit(2);
}
else if(projectPathFileType == FileType::REGULAR)
{
- cerr <<"Expected project path (" << projectPath << ") to be a directory, was a file" << endl;
+ ferr <<"Expected project path (" << projectPath << ") to be a directory, was a file" << endl;
exit(3);
}
}
-void validateFilePath(const char *projectConfPath)
+void validateFilePath(const _tinydir_char_t *projectConfPath)
{
FileType projectConfFileType = getFileType(projectConfPath);
if(projectConfFileType == FileType::FILE_NOT_FOUND)
{
string errMsg = "Invalid project.conf path: ";
- errMsg += projectConfPath;
+ errMsg += toUtf8(projectConfPath);
perror(errMsg.c_str());
exit(4);
}
else if(projectConfFileType == FileType::DIRECTORY)
{
- cerr << "Expected project path (" << projectConfPath << ") to be a file, was a directory" << endl;
+ ferr << "Expected project path (" << projectConfPath << ") to be a file, was a directory" << endl;
exit(5);
}
}
-const char *sourceFileExtensions[] = { "c", "cc", "cpp", "cxx" };
+const _tinydir_char_t *sourceFileExtensions[] = { TINYDIR_STRING("c"), TINYDIR_STRING("cc"), TINYDIR_STRING("cpp"), TINYDIR_STRING("cxx") };
bool isSourceFile(tinydir_file *file)
{
if(!file->is_reg)
return false;
- for(const char *sourceFileExtension : sourceFileExtensions)
+ for(const _tinydir_char_t *sourceFileExtension : sourceFileExtensions)
{
if(_tinydir_strcmp(sourceFileExtension, file->extension) == 0)
return true;
@@ -108,36 +114,36 @@ bool isSourceFile(tinydir_file *file)
return false;
}
-bool isPathSubPathOf(const string &path, const string &subPathOf)
+bool isPathSubPathOf(const FileString &path, const FileString &subPathOf)
{
return _tinydir_strncmp(path.c_str(), subPathOf.c_str(), subPathOf.size()) == 0;
}
-int buildProject(int argc, const char **argv)
+int buildProject(int argc, const _tinydir_char_t **argv)
{
if(argc > 2)
usageBuild();
OptimizationLevel optimizationLevel = OPT_LEV_NONE;
- string projectPath;
+ FileString projectPath;
for(int i = 0; i < argc; ++i)
{
- const char *arg = argv[i];
- if(strcmp(arg, "--debug") == 0)
+ const _tinydir_char_t *arg = argv[i];
+ if(_tinydir_strcmp(arg, TINYDIR_STRING("--debug")) == 0)
{
if(optimizationLevel != OPT_LEV_NONE)
{
- fprintf(stderr, "Error: Optimization level defined more than once. First defined as %s then as %s\n", asString(optimizationLevel), "debug");
+ ferr << "Error: Optimization level defined more than once. First defined as " << asString(optimizationLevel) << " then as debug" << endl;
usageBuild();
}
optimizationLevel = OPT_LEV_DEBUG;
}
- else if(strcmp(arg, "--release") == 0)
+ else if(_tinydir_strcmp(arg, TINYDIR_STRING("--release")) == 0)
{
if(optimizationLevel != OPT_LEV_NONE)
{
- fprintf(stderr, "Error: Optimization level defined more than once. First defined as %s then as %s\n", asString(optimizationLevel), "debug");
+ ferr << "Error: Optimization level defined more than once. First defined as " << asString(optimizationLevel) << " then as release" << endl;
usageBuild();
}
optimizationLevel = OPT_LEV_RELEASE;
@@ -146,7 +152,7 @@ int buildProject(int argc, const char **argv)
{
if(!projectPath.empty())
{
- fprintf(stderr, "Error: Project path was defined more than once. First defined as %s then as %s\n", projectPath.c_str(), arg);
+ ferr << "Error: Project path was defined more than once. First defined as " << projectPath << " then as " << arg << endl;
usageBuild();
}
projectPath = arg;
@@ -158,35 +164,43 @@ int buildProject(int argc, const char **argv)
// TODO: If projectPath is not defined and working directory does not contain project.conf, then search every parent directory until one is found
if(projectPath.empty())
- projectPath = ".";
+ projectPath = TINYDIR_STRING(".");
validateDirectoryPath(projectPath.c_str());
if(projectPath.back() != '/')
- projectPath += "/";
+ projectPath += TINYDIR_STRING("/");
- Result<string> projectRealPathResult = getRealPath(projectPath.c_str());
+ Result<FileString> projectRealPathResult = getRealPath(projectPath.c_str());
if(!projectRealPathResult)
{
- cerr << "Failed to get real path for: '" << projectPath << "': " << projectRealPathResult.getErrMsg() << endl;
+ ferr << "Failed to get real path for: '" << projectPath.c_str() << "': " << toFileString(projectRealPathResult.getErrMsg()) << endl;
exit(40);
}
projectPath = projectRealPathResult.unwrap();
- string projectConfFilePath = projectPath;
- projectConfFilePath += "/project.conf";
+ FileString projectConfFilePath = projectPath;
+ projectConfFilePath += TINYDIR_STRING("/project.conf");
validateFilePath(projectConfFilePath.c_str());
- SibsConfig sibsConfig(projectPath, optimizationLevel);
+ // TODO: Detect compiler to use at runtime. Should also be configurable
+ // by passing argument to `sibs build`
+#if OS_FAMILY == OS_FAMILY_POSIX
+ Compiler compiler = Compiler::GCC;
+#else
+ Compiler compiler = Compiler::MSVC;
+#endif
+
+ SibsConfig sibsConfig(compiler, projectPath, optimizationLevel);
Result<bool> result = Config::readFromFile(projectConfFilePath.c_str(), sibsConfig);
if(result.isErr())
{
- cerr << "Failed to read config: " << result.getErrMsg() << endl;
+ ferr << "Failed to read config: " << toFileString(result.getErrMsg()) << endl;
exit(6);
}
if(sibsConfig.getPackageName().empty())
{
- cerr << "project.conf is missing required field package.name" << endl;
+ ferr << "project.conf is missing required field package.name" << endl;
exit(10);
}
@@ -216,7 +230,8 @@ int buildProject(int argc, const char **argv)
{
if (isSourceFile(file))
{
- ninja.addSourceFile(file->path + sibsConfig.getProjectPath().size());
+ string filePathUtf8 = toUtf8(file->path + sibsConfig.getProjectPath().size());
+ ninja.addSourceFile(filePathUtf8.c_str());
}
else
{
@@ -226,66 +241,69 @@ int buildProject(int argc, const char **argv)
else
{
// TODO: If compiling without "test" option, do not add test source dir to ninja. Ninja logic will then not build tests
- if(!sibsConfig.getTestPath().empty() && isPathSubPathOf(file->path, sibsConfig.getTestPath()))
- ninja.addTestSourceDir(file->path);
+ if (!sibsConfig.getTestPath().empty() && isPathSubPathOf(file->path, sibsConfig.getTestPath()))
+ {
+ string filePathUtf8 = toUtf8(file->path);
+ ninja.addTestSourceDir(filePathUtf8.c_str());
+ }
else
walkDir(file->path, collectSourceFiles);
}
};
walkDir(projectPath.c_str(), collectSourceFiles);
- string buildPath = projectPath + "/sibs-build/";
+ FileString buildPath = projectPath + TINYDIR_STRING("/sibs-build/");
switch(sibsConfig.getOptimizationLevel())
{
case OPT_LEV_DEBUG:
- buildPath += "debug";
+ buildPath += TINYDIR_STRING("debug");
break;
case OPT_LEV_RELEASE:
- buildPath += "release";
+ buildPath += TINYDIR_STRING("release");
break;
}
Result<bool> buildFileResult = ninja.build(sibsConfig, buildPath.c_str());
if(buildFileResult.isErr())
{
- cerr << "Failed to build ninja file: " << buildFileResult.getErrMsg() << endl;
+ ferr << "Failed to build ninja file: " << toFileString(buildFileResult.getErrMsg()) << endl;
exit(7);
}
return 0;
}
-void newProjectCreateMainDir(const string &projectPath)
+void newProjectCreateMainDir(const FileString &projectPath)
{
Result<bool> createProjectDirResult = createDirectoryRecursive(projectPath.c_str());
if(createProjectDirResult.isErr())
{
- cerr << "Failed to create project main directory: " << createProjectDirResult.getErrMsg() << endl;
+ ferr << "Failed to create project main directory: " << toFileString(createProjectDirResult.getErrMsg()) << endl;
exit(20);
}
}
-void createProjectSubDir(const string &dir)
+void createProjectSubDir(const FileString &dir)
{
Result<bool> createProjectDirResult = createDirectoryRecursive(dir.c_str());
if(createProjectDirResult.isErr())
{
- cerr << "Failed to create directory in project: " << createProjectDirResult.getErrMsg() << endl;
+ ferr << "Failed to create directory in project: " << toFileString(createProjectDirResult.getErrMsg()) << endl;
exit(20);
}
}
-void createProjectFile(const string &projectFilePath, const string &fileContent)
+void createProjectFile(const FileString &projectFilePath, const string &fileContent)
{
Result<bool> fileOverwriteResult = fileOverwrite(projectFilePath.c_str(), fileContent.c_str());
if(fileOverwriteResult.isErr())
{
- cerr << "Failed to create project file: " << fileOverwriteResult.getErrMsg() << endl;
+ ferr << "Failed to create project file: " << toFileString(fileOverwriteResult.getErrMsg()) << endl;
exit(20);
}
}
-void newProjectCreateConf(const string &projectName, const string &projectType, const string &projectPath)
+void newProjectCreateConf(const string &projectName, const string &projectType, const FileString &projectPath)
{
string projectConfStr = "[package]\n";
projectConfStr += "name = \"" + projectName + "\"\n";
@@ -293,98 +311,102 @@ void newProjectCreateConf(const string &projectName, const string &projectType,
projectConfStr += "version = \"0.1.0\"\n\n";
projectConfStr += "[dependencies]\n";
- string projectConfPath = projectPath;
- projectConfPath += "/project.conf";
+ FileString projectConfPath = projectPath;
+ projectConfPath += TINYDIR_STRING("/project.conf");
Result<bool> fileOverwriteResult = fileOverwrite(projectConfPath.c_str(), projectConfStr.c_str());
if(fileOverwriteResult.isErr())
{
- cerr << "Failed to create project.conf: " << fileOverwriteResult.getErrMsg() << endl;
+ ferr << "Failed to create project.conf: " << toFileString(fileOverwriteResult.getErrMsg()) << endl;
exit(20);
}
}
// This can be replaced with createDirectory and fileOverwrite, but it's not important
// so there is no reason to do it (right now)
-Result<ExecResult> gitInitProject(const string &projectPath)
+Result<ExecResult> gitInitProject(const FileString &projectPath)
{
- string cmd = "git init '";
+ FileString cmd = TINYDIR_STRING("git init \"");
cmd += projectPath;
- cmd += "'";
+ cmd += TINYDIR_STRING("\"");
return exec(cmd.c_str());
}
-int newProject(int argc, const char **argv)
+int newProject(int argc, const _tinydir_char_t **argv)
{
if(argc != 2)
{
- cerr << "Expected 'new' command to be followed by two arguments - project name and type of project (--exec, --static or --dynamic)" << endl << endl;
+ ferr << "Expected 'new' command to be followed by two arguments - project name and type of project (--exec, --static or --dynamic)" << endl << endl;
usageNew();
}
- Result<string> cwdResult = getCwd();
+ Result<FileString> cwdResult = getCwd();
if(cwdResult.isErr())
{
- cerr << "Failed to get current working directory: " << cwdResult.getErrMsg() << endl;
+ ferr << "Failed to get current working directory: " << toFileString(cwdResult.getErrMsg()) << endl;
exit(20);
}
- string projectName = argv[0];
- string projectPath = cwdResult.unwrap();
- projectPath += "/";
- projectPath += projectName;
+ string projectName = toUtf8(argv[0]);
+ FileString projectPath = cwdResult.unwrap();
+ projectPath += TINYDIR_STRING("/");
+ projectPath += toFileString(projectName);
bool projectPathExists = getFileType(projectPath.c_str()) != FileType::FILE_NOT_FOUND;
if(projectPathExists)
{
- cerr << "Unable to create a new project at path '" << projectPath << "'. A file or directory already exists in the same location" << endl;
+ ferr << "Unable to create a new project at path '" << projectPath << "'. A file or directory already exists in the same location" << endl;
exit(20);
}
- const char *projectType = argv[1];
+ const _tinydir_char_t *projectType = argv[1];
string projectTypeConf;
- if(strcmp(projectType, "--exec") == 0)
+ if(_tinydir_strcmp(projectType, TINYDIR_STRING("--exec")) == 0)
projectTypeConf = "executable";
- else if(strcmp(projectType, "--static") == 0)
+ else if(_tinydir_strcmp(projectType, TINYDIR_STRING("--static")) == 0)
projectTypeConf = "static";
- else if(strcmp(projectType, "--dynamic") == 0)
+ else if(_tinydir_strcmp(projectType, TINYDIR_STRING("--dynamic")) == 0)
projectTypeConf = "dynamic";
else
{
- cerr << "Expected project type to be either --exec, --static or --dynamic; was: " << projectType << endl << endl;
+ ferr << "Expected project type to be either --exec, --static or --dynamic; was: " << projectType << endl << endl;
usageNew();
}
newProjectCreateMainDir(projectPath);
newProjectCreateConf(projectName, projectTypeConf, projectPath);
- createProjectSubDir(projectPath + "/src");
- createProjectSubDir(projectPath + "/include");
- createProjectFile(projectPath + "/src/main.cpp", "#include <cstdio>\n\nint main()\n{\n return 0;\n}\n");
+ createProjectSubDir(projectPath + TINYDIR_STRING("/src"));
+ createProjectSubDir(projectPath + TINYDIR_STRING("/include"));
+ createProjectFile(projectPath + TINYDIR_STRING("/src/main.cpp"), "#include <cstdio>\n\nint main()\n{\n return 0;\n}\n");
// We are ignoring git init result on purpose. If it fails, just ignore it; not important
gitInitProject(projectPath);
return 0;
}
-int main(int argc, const char **argv)
+#if OS_FAMILY == OS_FAMILY_POSIX
+int main(int argc, const _tinydir_char_t **argv)
+#else
+int wmain(int argc, const _tinydir_char_t **argv)
+#endif
{
unordered_map<string, string> param;
unordered_set<string> flags;
for(int i = 1; i < argc; ++i)
{
- const char *arg = argv[i];
+ const _tinydir_char_t *arg = argv[i];
int subCommandArgCount = argc - i - 1;
- const char **subCommandArgPtr = argv + i + 1;
- if(strcmp(arg, "build") == 0)
+ const _tinydir_char_t **subCommandArgPtr = argv + i + 1;
+ if(_tinydir_strcmp(arg, TINYDIR_STRING("build")) == 0)
{
return buildProject(subCommandArgCount, subCommandArgPtr);
}
- else if(strcmp(arg, "new") == 0)
+ else if(_tinydir_strcmp(arg, TINYDIR_STRING("new")) == 0)
{
return newProject(subCommandArgCount, subCommandArgPtr);
}
else
{
- cerr << "Expected command to be either 'build' or 'new', was: " << arg << endl << endl;
+ ferr << "Expected command to be either 'build' or 'new', was: " << arg << endl << endl;
usage();
}
}