blob: 72ae00d5c6370e552bc5ec8ef676d2f92e91e593 [file] [log] [blame] [edit]
/*
** 2025-12-26
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file implements a substitute process entry point for windows
** that correctly interprets command-line arguments as UTF-8. This is
** a work-around for the (unfixed) Windows bug known as "WorstFit" and
** described at:
**
** * https://news.ycombinator.com/item?id=42647101
**
** USAGE:
**
** If you have a command-line program coded to C-language standard in which
** the entry point is:
**
** int main(int argc, char **argv){...}
**
** That does not work on Windows if there are non-ASCII characters on the
** command line. Programs are expected to use an alternative entry point:
**
** int wmain(int wargc, wchar_t **wargv){...}
**
** This file implements _wmain() but then converts all of the wargv elements
** to UTF-8 and passes them off to utf8_main().
**
** So, a command-line tool that implements the standard entry point can be
** modified by adding the following lines just prior to main():
**
** #ifdef _WIN32
** #define main utf8_main
** #endif
**
** Then, include this file in the list of files that implement the program,
** and the program will work correctly, even on Windows.
*/
#include <windows.h>
#include <stdio.h>
extern int utf8_main(int,char**);
int wmain(int argc, wchar_t **wargv){
int rc, i;
char **argv = malloc( sizeof(char*) * (argc+1) );
char **orig = argv;
if( argv==0 ){
fprintf(stderr, "malloc failed\n");
exit(1);
}
for(i=0; i<argc; i++){
int nByte = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, 0, 0, 0, 0);
if( nByte==0 ){
argv[i] = 0;
}else{
argv[i] = malloc( nByte );
if( argv[i]==0 ){
fprintf(stderr, "malloc failed\n");
exit(1);
}
nByte = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, argv[i],nByte,0,0);
if( nByte==0 ){
free(argv[i]);
argv[i] = 0;
}
}
}
argv[argc] = 0;
rc = utf8_main(argc, argv);
for(i=0; i<argc; i++) free(orig[i]);
free(argv);
return rc;
}