stagit-5hif7y

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 82411e09915bc3697b627111aedc9d4d9c671a50
parent 293e00857a1605229efa888988392d1c16f67e63
Author: 5hif7y <[email protected]>
Date:   Tue, 22 Apr 2025 18:07:40 -0300

w10 support

Diffstat:
Abuild.bat | 102+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mreallocarray.c | 2+-
Mstagit-index.c | 8++++++--
Mstagit.c | 14+++++++++-----
Awincompat.h | 153+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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 */