commit 82411e09915bc3697b627111aedc9d4d9c671a50
parent 293e00857a1605229efa888988392d1c16f67e63
Author: 5hif7y <[email protected]>
Date: Tue, 22 Apr 2025 18:07:40 -0300
w10 support
Diffstat:
5 files changed, 271 insertions(+), 8 deletions(-)
diff --git a/build.bat b/build.bat
@@ -0,0 +1,102 @@
+@echo off
+setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
+
+:: compilation settings
+set CC=cl
+set CFLAGS= /D _CRT_SECURE_NO_WARNINGS /nologo /W3
+set LDFLAGS=/link /NOIMPLIB /NOEXP /LTCG git2.lib Advapi32.lib Winhttp.lib Ole32.lib Rpcrt4.lib Crypt32.lib zlib.lib pcre.lib
+
+:: common shared sources
+set COMPATSRC=reallocarray.c strlcat.c strlcpy.c
+
+:: main
+set "ARG=%~1"
+
+if "%ARG%"=="" (
+ call :build_target stagit
+ echo -----
+ call :build_target stagit-index
+ goto :eof
+)
+
+if /I "%ARG%"=="stagit" (
+ call :build_target stagit
+ goto :eof
+)
+
+if /I "%ARG%"=="stagit-index" (
+ call :build_target stagit-index
+ goto :eof
+)
+
+if /I "%ARG%"=="clean" (
+ call :clean
+ goto :eof
+)
+
+if /I "%ARG%"=="clean-all" (
+ call :clean_all
+ goto :eof
+)
+
+:: call help
+echo Comando desconocido: %ARG%
+call :show_help
+goto :eof
+
+:: success msg
+:success_msg
+powershell -Command "Write-Host 'Build success: %BIN%.' -ForegroundColor Green"
+goto:eof
+
+:: failure msg
+:failure_msg
+powershell -Command "Write-Host 'Build failed: %BIN% not found.' -ForegroundColor Red"
+goto :eof
+
+:: compilation function
+:build_target
+set SRC=%1.c
+set BIN=%1.exe
+echo Building %BIN%...
+%CC% /Fe:%BIN% %CFLAGS% %SRC% %COMPATSRC% %LDFLAGS%
+if exist %BIN% (
+ call :success_msg
+) else (
+ call :failure_msg
+)
+goto :eof
+
+:: clean function
+:clean
+echo Cleaning *.obj...
+del /q *.obj 2>nul
+goto :eof
+
+:: clean all function
+:clean_all
+echo Cleaning *.obj and *.exe...
+del /q *.obj *.exe 2>nul
+goto :eof
+
+:: help function
+:show_help
+ echo Unknown command: %1
+ echo Usage:
+ echo build.bat - build all
+ echo build.bat stagit - build stagit.exe
+ echo build.bat stagit-index - build stagit-index.exe
+ echo build.bat clean - delete .obj files
+ echo build.bat clean-all - delete .obj and .exe files
+ echo.
+ echo Required libraries:
+ echo [MSVC/Windows SDK]
+ echo Advapi32.lib Winhttp.lib Ole32.lib Rpcrt4.lib Crypt32.lib
+ echo [External]
+ echo git2.lib zlib.lib pcre.lib
+ echo.
+ echo Tip: I used and recommend VCPKG to install the external libraries.
+goto :eof
+
+endlocal
+
diff --git a/reallocarray.c b/reallocarray.c
@@ -25,7 +25,7 @@
* This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
* if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
*/
-#define MUL_NO_OVERFLOW (1UL << (sizeof(size_t) * 4))
+#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
void *
reallocarray(void *optr, size_t nmemb, size_t size)
diff --git a/stagit-index.c b/stagit-index.c
@@ -1,10 +1,14 @@
-#include <err.h>
+#ifdef _WIN32
+ #include "wincompat.h"
+#else
+ #include <err.h>
+ #include <unistd.h>
+#endif
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
-#include <unistd.h>
#include <git2.h>
diff --git a/stagit.c b/stagit.c
@@ -1,16 +1,20 @@
#include <sys/stat.h>
#include <sys/types.h>
-#include <err.h>
+#ifdef _WIN32
+ #include "wincompat.h"
+#else
+ #include <err.h>
+ #include <libgen.h>
+ #include <unistd.h>
+#endif
#include <errno.h>
-#include <libgen.h>
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
-#include <unistd.h>
#include <git2.h>
@@ -673,9 +677,9 @@ printshowfile(FILE *fp, struct commitinfo *ci)
total = sizeof(linestr) - 2;
if (changed > total) {
if (add)
- add = ((float)total / changed * add) + 1;
+ add = (size_t)(((float)total / changed * add) + 1);
if (del)
- del = ((float)total / changed * del) + 1;
+ del = (size_t)(((float)total / changed * del) + 1);
}
memset(&linestr, '+', add);
memset(&linestr[add], '-', del);
diff --git a/wincompat.h b/wincompat.h
@@ -0,0 +1,153 @@
+/* C99 (ISO/IEC 9899:1999) - 5hif7y */
+/* A little helper to force POSIX compatibility for suckless tools on Windows */
+
+#ifndef WINCOMPAT_H
+#define WINCOMPAT_H
+#ifdef _WIN32
+
+//#define _CRT_SECURE_NO_WARNINGS /* TODO: use secure implementation 'strcpy' to 'strcpy_s' */
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <sys/stat.h>
+#include <io.h>
+#include <direct.h>
+#include <fcntl.h>
+#include <stdlib.h>
+
+/* --------- posix datatype --------- */
+typedef int mode_t;
+
+/* --------- misc defines --------- */
+#define PATH_MAX 260
+#ifdef _MSC_VER
+ #define access _access
+ #define fdopen _fdopen /* TODO: reimplement 'fdopen' for Windows MSVC */
+ #define umask _umask
+ #define chmod _chmod
+#endif
+#define warnx(fmt, ...) (fprintf(stderr, fmt "\n", ##__VA_ARGS__))
+#define err(exitcode, fmt, ...) do { \
+ fprintf(stderr, fmt "\n", ##__VA_ARGS__); \
+ exit(exitcode); \
+} while (0)
+#define errx(exitcode, fmt, ...) err(exitcode, fmt, ##__VA_ARGS__)
+/* if your toolchain is using MSVC, use the native implementation '_strdup' */
+#if defined(_MSC_VER)
+ #define strdup _strdup
+/* Use this if your toolchain doesn't have an 'strdup' implementation */
+#elif defined(CUSTOM_STRDUP)
+ static char *custom_strdup(const char *s){
+ if(!s){ return NULL;}
+ size_t len = strlen(s) + 1;
+ char *copy = malloc(len);
+ if (copy) { memcpy(copy, s, len); }
+ return copy;
+ }
+ #define strcup custom_strdup
+#endif /* _MSC_VER xor CUSTOM_STRDUP */
+
+/* --------- posix functions reimplementations --------- */
+static int mkstemp(char *templte){
+ char *XXXXXX = strstr(templte, "XXXXXX");
+ if (!XXXXXX || strlen(XXXXXX) != 6) {
+ return -1;
+ }
+ for (int i = 0; i < 100; ++i) {
+ for (int j = 0; j < 6; ++j) {
+ XXXXXX[j] = 'A' + rand() % 26;
+ }
+ int fd = _open(templte, _O_RDWR | _O_CREAT | _O_EXCL, _S_IREAD | _S_IWRITE);
+ if (fd != -1) {
+ return fd;
+ }
+ }
+ return -1;
+}
+
+static char *win_basename(const char *path){
+ if (!path || !*path){ return NULL; }
+
+ const char *last_slash = strrchr(path, '\\');
+ const char *last_fslash = strrchr(path, '/');
+ const char *base = path;
+
+ if (last_slash && last_fslash){
+ base = (last_slash > last_fslash) ? last_slash + 1 : last_fslash + 1;
+ }
+ else if (last_slash) {
+ base = last_slash + 1;
+ }
+ else if (last_fslash){
+ base = last_fslash + 1;
+ }
+ return strdup(base);
+}
+#define basename(path) win_basename(path)
+
+static char *win_dirname(char *path){
+ static char buffer[MAX_PATH];
+ char *slash;
+ if (!path || !*path){
+ strcpy(buffer, ".");
+ return buffer;
+ }
+ strncpy(buffer, path, MAX_PATH);
+ buffer[MAX_PATH - 1] = '\0'; // prevenir falta de terminación nula
+ slash = strrchr(buffer, '\\');
+ if (!slash){
+ slash = strrchr(buffer, '/');
+ }
+ if (slash){
+ *slash = '\0';
+ } else {
+ strcpy(buffer, ".");
+ }
+ return buffer;
+}
+#define dirname(path) win_dirname(path)
+
+static char *realpath(const char *path, char *resolved_path){
+ if(!resolved_path){ resolved_path = (char*)malloc(MAX_PATH); }
+ _fullpath(resolved_path, path, MAX_PATH);
+ return resolved_path;
+}
+
+static int win_mkdir(const char *path, mode_t mode){
+ (void)mode; /* discard unused variable in a way the compiler doesn't complain */
+ return _mkdir(path);
+}
+#define mkdir(path, mode) win_mkdir(path, mode)
+
+/* --------- access --------- */
+#ifndef F_OK
+#define F_OK 0
+#endif
+
+/* --------- permission macros --------- */
+#define S_IRWXU 0700
+#define S_IRUSR 0400
+#define S_IWUSR 0200
+#define S_IXUSR 0100
+#define S_IRWXG 0070
+#define S_IRGRP 0040
+#define S_IWGRP 0020
+#define S_IXGRP 0010
+#define S_IRWXO 0007
+#define S_IROTH 0004
+#define S_IWOTH 0002
+#define S_IXOTH 0001
+#define S_ISUID 0004000
+#define S_ISGID 0002000
+#define S_ISVTX 0001000
+
+/* --------- S_ISXXX macros --------- */
+#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
+#define S_ISBLK(m) (0) // doesn't exist in Windows
+#define S_ISFIFO(m) (0)
+#define S_ISLNK(m) (0)
+#define S_ISSOCK(m) (0)
+
+#endif /* _WIN32 */
+#endif /* WINCOMPAT_H */