AoikWinWhich - which program implemented in various languages
AoikWinWhich-Bash
#!/usr/bin/env bash
function strings_has {
#/
local item="$1"
#/
local elem
for elem in "${@:2}";
do
[[ "$elem" == "$item" ]] && return 0
done
#/
return 1
}
function strings_uniq {
#/ $1 is name of result variable to set on return
local resvar="$1"
#/ $2 upwards are array items
shift
local item_s=("${@}")
#/
local item_new_s=()
for item in "${item_s[@]}"
do
strings_has "$item" "${item_new_s[@]}" || item_new_s+=("$item")
done
#/
eval $resvar='( "${item_new_s[@]}" )'
}
function strings_trim()
{
#/ $1 is name of result variable to set on return
local resvar="$1"
#/ $2 upwards are array items
shift
local item_s=("${@}")
#/
local item_new_s=()
local item_new
for item in "${item_s[@]}"
do
if [[ "$item" =~ ^[[:space:]]*([^[:space:]].*[^[:space:]])[[:space:]]*$ ]]
then
item_new="${BASH_REMATCH[1]}"
else
item_new="$item"
fi
item_new_s+=("$item_new")
done
#/
eval $resvar='( "${item_new_s[@]}" )'
}
function strings_unempty()
{
#/ $1 is name of result variable to set on return
local resvar="$1"
#/ $2 upwards are array items
shift
local item_s=("${@}")
#/
local item_new_s=()
for item in "${item_s[@]}"
do
if [ -n "$item" ]; then
item_new_s+=("$item")
fi
done
#/
eval $resvar='( "${item_new_s[@]}" )'
}
function strings_lower()
{
#/ $1 is name of result variable to set on return
local resvar="$1"
#/ $2 upwards are array items
shift
local item_s=("${@}")
#/
local item_new_s=()
for item in "${item_s[@]}"
do
item_new_s+=("${item,,}")
done
#/
eval $resvar='( "${item_new_s[@]}" )'
}
function strings_anyisendof {
#/
local item="$1"
#/
local elem
for elem in "${@:2}";
do
[[ "$item" == *"$elem" ]] && return 0
done
#/
return 1
}
function find_executable {
#/ $1 is name of result variable to set on return
local resvar="$1"
#/
local prog="$2"
#/ 6qhHTHF
#/ split into a list of extensions
OIFS="$IFS"
IFS=';'
[ -z "$PATHEXT" ] && ext_s=() || ext_s=( $PATHEXT )
IFS="$OIFS"
#/ 2pGJrMW
#/ strip
strings_trim ext_s "${ext_s[@]}"
#/ 2gqeHHl
#/ remove empty
strings_unempty ext_s "${ext_s[@]}"
#/ 2zdGM8W
#/ convert to lowercase
strings_lower ext_s "${ext_s[@]}"
#/ 2fT8aRB
#/ uniquify
strings_uniq ext_s "${ext_s[@]}"
#/ 6mPI0lg
OIFS="$IFS"
IFS=':'
## In Cygwin, |;| in PATH is converted to |:|.
[ -z "$PATH" ] && dir_path_s=() || dir_path_s=( $PATH )
IFS="$OIFS"
#/ 5rT49zI
#/ insert empty dir path to the beginning
##
## Empty dir handles the case that |prog| is a path, either relative or
## absolute. See code 7rO7NIN.
dir_path_s=( '' "${dir_path_s[@]}")
#/ 2klTv20
#/ uniquify
strings_uniq dir_path_s "${dir_path_s[@]}"
#/ 6bFwhbv
exe_path_s=()
for dir_path in "${dir_path_s[@]}"; do
#/ 7rO7NIN
#/ synthesize a path with the dir and prog
if [ "$dir_path" == '' ]; then
path="$prog"
else
path="$dir_path/$prog"
fi
#/ 6kZa5cq
## assume the path has extension, check if it is an executable
if strings_anyisendof "$path" "${ext_s[@]}"; then
if [ -f "$path" ]; then
exe_path_s=( "${exe_path_s[@]}" "$path" )
fi
fi
#/ 2sJhhEV
## assume the path has no extension
for ext in "${ext_s[@]}"; do
#/ 6k9X6GP
#/ synthesize a new path with the path and the executable extension
path_plus_ext="$path$ext"
#/ 6kabzQg
#/ check if it is an executable
if [ -f "$path_plus_ext" ]; then
exe_path_s=( "${exe_path_s[@]}" "$path_plus_ext" )
fi
done
done
#/ 8swW6Av
#/ uniquify
strings_uniq exe_path_s "${exe_path_s[@]}"
#/
eval $resvar='( "${exe_path_s[@]}" )'
}
function main {
#/ 9mlJlKg
if [ "$#" != "1" ]; then
#/ 7rOUXFo
#/ print program usage
echo 'Usage: aoikwinwhich PROG'
echo ''
echo '#/ PROG can be either name or path'
echo 'aoikwinwhich notepad.exe'
echo 'aoikwinwhich C:\Windows\notepad.exe'
echo ''
echo '#/ PROG can be either absolute or relative'
echo 'aoikwinwhich C:\Windows\notepad.exe'
echo 'aoikwinwhich Windows\notepad.exe'
echo ''
echo '#/ PROG can be either with or without extension'
echo 'aoikwinwhich notepad.exe'
echo 'aoikwinwhich notepad'
echo 'aoikwinwhich C:\Windows\notepad.exe'
echo 'aoikwinwhich C:\Windows\notepad'
#/ 3nqHnP7
return
fi
#/ 9m5B08H
#/ get name or path of a program from cmd arg
prog="$1"
#/ 8ulvPXM
#/ find executables
find_executable path_s "$prog"
#/ 5fWrcaF
#/ has found none, exit
if [ "${#path_s[@]}" == "0" ]; then
#/ 3uswpx0
return
fi
#/ 9xPCWuS
#/ has found some, output
printf "%s\n" "${path_s[@]}"
#/ 4s1yY1b
return
}
main "$@"
AoikWinWhich-Batch
@echo off
setlocal EnableDelayedExpansion
::/
call :main %*
exit /B
::/ define a |strIndex| func
::# Copied from: http://stackoverflow.com/a/22928259
::--BEG
:strIndex string substring [instance]
REM Using adaptation of strLen function found at http://www.dostips.com/DtCodeCmdLib.php#Function.strLen
SETLOCAL ENABLEDELAYEDEXPANSION
SETLOCAL ENABLEEXTENSIONS
IF "%~2" EQU "" SET Index=-1 & GOTO strIndex_end
IF "%~3" EQU "" (SET Instance=1) ELSE (SET Instance=%~3)
SET Index=-1
SET String=%~1
SET "str=A%~1"
SET "String_Length=0"
FOR /L %%A IN (12,-1,0) DO (
SET /a "String_Length|=1<<%%A"
FOR %%B IN (!String_Length!) DO IF "!str:~%%B,1!"=="" SET /a "String_Length&=~1<<%%A"
)
SET "sub=A%~2"
SET "Substring_Length=0"
FOR /L %%A IN (12,-1,0) DO (
SET /a "Substring_Length|=1<<%%A"
FOR %%B IN (!Substring_Length!) DO IF "!sub:~%%B,1!"=="" SET /a "Substring_Length&=~1<<%%A"
)
IF %Substring_Length% GTR %String_Length% GOTO strIndex_end
SET /A Searches=%String_Length%-%Substring_Length%
IF %Instance% GTR 0 (
FOR /L %%n IN (0,1,%Searches%) DO (
CALL SET StringSegment=%%String:~%%n,!Substring_Length!%%
IF "%~2" EQU "!StringSegment!" SET /A Instance-=1
IF !Instance! EQU 0 SET Index=%%n & GOTO strIndex_end
)) ELSE (
FOR /L %%n IN (%Searches%,-1,0) DO (
CALL SET StringSegment=%%String:~%%n,!Substring_Length!%%
IF "%~2" EQU "!StringSegment!" SET /A Instance+=1
IF !Instance! EQU 0 SET Index=%%n & GOTO strIndex_end
))
:strIndex_end
EXIT /B %Index%
::--END
:items_exists
REM %~1: items' array-like variable name prefix
REM %~2: items' count
REM %~3: item to check if it exists in the items
::/
setlocal
::/
set items_vnp=%~1
::/
set items_cnt=%~2
::/
set item=%~3
::/
set /A items_imax=items_cnt-1
for /L %%m in (0,1,!items_imax!) do (
call set "cur_item=%%!items_vnp![%%m]%%"
if "!item!" == "!cur_item!" (
exit /B 0
)
)
exit /B 1
goto:eof
:exts_anyisendof
REM %~1: exts' array-like variable name prefix
REM %~2: exts' count
REM %~3: path to check if it ends with one of the exts
::/
setlocal
::/
set exts_vnp=%~1
::/
set exts_cnt=%~2
::/
set path=%~3
::/
set /A exts_imax=exts_cnt-1
for /L %%x in (0,1,!exts_imax!) do (
call set "ext=%%!exts_vnp![%%x]%%"
::/ check if the path ends with one of the exts
REM :: Tried using |findstr| but very slow.
REM --BEG
REM set regex=.*\!ext!
REM echo.!path!|>nul findstr /I /rx "!regex!"
REM --END
call :strIndex "!path!" "." -1
set ext_dot_idx=!errorlevel!
if ext_dot_idx neq -1 (
call set path_ext=%%path:~!ext_dot_idx!%%
if /I "!path_ext!"=="!ext!" (
exit /B 0
)
)
)
exit /B 1
goto:eof
::/
:find_executable
REM %~1: prog name or path
::/
setlocal
::/
set prog=%~1
::/ 6qhHTHF
::/ split into a list of extensions
set i=0
for %%e in ("%PATHEXT:;=";"%") do (
::/
set _ext=%%~e
::/ 2gqeHHl
REM:: remove empty
if not "!_ext!" == "" (
call set "ext_s[%%i%%]=!_ext!"
set /A i=i+1
)
)
set /A exts_cnt=i
set /A ext_imax=exts_cnt-1
::/ 6bFwhbv
set i=0
::: loop index
set res_path_i=0
::: result index
for %%x in ("" "%PATH:;=";"%") do (
::/ 7rO7NIN
REM :: synthesize a path with the dir and prog
if "%%~x" == "" (
if "!i!" == "0" (
set path=%prog%
) else (
::/ ignore empty dir unless it's the first
set path=
)
) else (
set path=%%~x\%prog%
)
::/
if not "!path!" == "" (
::/ 6kZa5cq
REM :: assume the path has extension, check if it is an executable
if exist "!path!" if not exist "!path!\" (
::/ check if the path ends with one of the exts
call :exts_anyisendof "ext_s" "!exts_cnt!" "!path!"
::: Y
if "!errorlevel!" == "0" (
::/ check if the path exists in result
call :items_exists "res_path_s" "!res_path_i!" "!path!"
::: N
if not "!errorlevel!" == "0" (
::/ add to res_path_s
call set "res_path_s[!res_path_i!]=!path!"
::/
set /A res_path_i=res_path_i+1
)
)
)
::/ 2sJhhEV
REM :: assume the path has no extension
for /L %%k in (0,1,%ext_imax%) do (
::/ 6k9X6GP
REM :: synthesize a new path with the path and the executable extension
set ext=!ext_s[%%k]!
set path_plus_ext=!path!!ext!
::/ 6kabzQg
REM :: check if it is an executable
if exist "!path_plus_ext!" if not exist "!path_plus_ext!\" (
::/ check if the path exists in result
call :items_exists "res_path_s" "!res_path_i!" "!path_plus_ext!"
::: N
if not "!errorlevel!" == "0" (
::/ add to res_path_s
call set "res_path_s[!res_path_i!]=!path_plus_ext!"
::/
set /A res_path_i=res_path_i+1
)
)
)
)
::/
set /A i=i+1
)
::/ 5fWrcaF
::/ has found none, exit
if %res_path_i% equ 0 (
::/ 3uswpx0
exit /B
)
::/ 9xPCWuS
::/ has found some, output
set /A res_path_imax=res_path_i-1
for /L %%n in (0,1,%res_path_imax%) do (
echo !res_path_s[%%n]!
)
goto:eof
:main
::/
setlocal
::/ 9mlJlKg
::/ check if one cmd arg is given
set args_len=0
for %%x in (%*) do set /A args_len+=1
:: N
if not "%args_len%" == "1" (
::/ 7rOUXFo
::/ print program usage
echo.Usage: aoikwinwhich PROG
echo.
echo.#/ PROG can be either name or path
echo.aoikwinwhich notepad.exe
echo.aoikwinwhich C:\Windows\notepad.exe
echo.
echo.#/ PROG can be either absolute or relative
echo.aoikwinwhich C:\Windows\notepad.exe
echo.aoikwinwhich Windows\notepad.exe
echo.
echo.#/ PROG can be either with or without extension
echo.aoikwinwhich notepad.exe
echo.aoikwinwhich notepad
echo.aoikwinwhich C:\Windows\notepad.exe
echo.aoikwinwhich C:\Windows\notepad
::/ 3nqHnP7
exit /B
)
::/ 9m5B08H
::/ get name or path of a program from cmd arg
set prog=%~1
::/ 8ulvPXM
::/ find executables
call :find_executable "!prog!"
::/ 4s1yY1b
exit /B
goto:eof
AoikWinWhich-C
//
#include "stdafx.h"
#include <windows.h>
#include <Shlwapi.h>
#pragma comment(lib, "Shlwapi.lib")
//
typedef char const * String;
//
typedef struct StringNode
{
String str;
struct StringNode* next;
} StringNode;
//
typedef struct StringList
{
StringNode* head;
StringNode* end;
size_t count;
} StringList;
//
StringNode* stringnode_create(String str) {
//
StringNode* str_node = (StringNode*)malloc(sizeof(StringNode));
//
str_node->str = str;
str_node->next = NULL;
//
return str_node;
}
//
StringList* stringlist_create() {
//
StringList* str_list = (StringList*)malloc(sizeof(StringList));
//
str_list->head = NULL;
str_list->end = NULL;
str_list->count = 0;
//
return str_list;
}
//
void stringlist_add_head(StringList* str_list, String str) {
//
StringNode* item = stringnode_create(str);
//if strlist->end
if (str_list->count == 0) {
//
assert(!str_list->head);
assert(!str_list->end);
//
str_list->head = item;
str_list->end = item;
// new end clears "next"
str_list->end->next = NULL;
}
else {
//
assert(str_list->head);
assert(str_list->end);
// new head links to old head
item->next = str_list->head;
// set new head
str_list->head = item;
}
//
str_list->count += 1;
}
//
void stringlist_add_end(StringList* str_list, String str) {
//
StringNode* item = stringnode_create(str);
//if strlist->end
if (str_list->count == 0) {
//
assert(!str_list->head);
assert(!str_list->end);
//
str_list->head = item;
str_list->end = item;
// new end clears "next"
str_list->end->next = NULL;
}
else {
//
assert(str_list->head);
assert(str_list->end);
// old end links to new end
str_list->end->next = item;
// set new end
str_list->end = item;
// new end clears "next"
str_list->end->next = NULL;
}
//
str_list->count += 1;
}
//
BOOL stringlist_contains(StringList* str_list, String str) {
//
StringNode* node = str_list->head;
while (node) {
// If two strings are equal
if (!strcmp(node->str, str)) {
return TRUE;
};
//
node = node->next;
}
return FALSE;
}
//
void stringlist_uniq(
StringList* res_list, // Result
StringList* str_list)
{
//
StringNode* node = str_list->head;
while (node) {
//
if (!stringlist_contains(res_list, node->str)) {
// String "node->str" is changed ownership
stringlist_add_end(res_list, node->str);
// Clear old pointer
node->str = NULL;
};
//
node = node->next;
}
}
//
void stringlist_del(StringList* str_list) {
//
StringNode* node = str_list->head;
while (node) {
//
StringNode* next = node->next;
//
if (node->str) {
//
free((void*)node->str);
//
node->str = NULL;
}
node->next = NULL;
free(node);
//
node = next;
}
//
str_list->head = NULL;
str_list->end = NULL;
str_list->count = 0;
//
free(str_list);
}
//
void stringlist_del_v2(
StringList** str_list_pp // "pp" means pointer pointer
) {
//
assert(str_list_pp);
assert(*str_list_pp);
//
stringlist_del(*str_list_pp);
// Set the "StringList pointer" to NULL, in order to avoid address violation.
*str_list_pp = NULL;
}
//
char* string_copy_new(const char* str) {
//
size_t str_bytes_cnt = sizeof(char) * (strlen(str) + 1);
//
char* str_copy = (char *)malloc(str_bytes_cnt);
//
memcpy(str_copy, str, str_bytes_cnt);
str_copy[str_bytes_cnt - 1] = '\0';
//
return str_copy;
}
//
void string_split(StringList* str_s, String str, char sep) {
//
char sep_str[2];
sep_str[0] = sep;
sep_str[1] = '\0';
//
size_t str_len = strlen(str);
size_t start = 0;
while (TRUE) {
//
String substr_start = str + start;
// 2a1XF8a
// Can be 0 when the first char is the sep char.
size_t substr_cnt = strcspn(substr_start, sep_str);
// "+ 1" for null terminator.
//
// "substr_cnt" at 2a1XF8a being 0 is well handled.
size_t substr_byte_cnt = sizeof(char) * (substr_cnt + 1);
//
char* substr = malloc(substr_byte_cnt);
// "substr_cnt" at 2a1XF8a being 0 is well handled.
memcpy(substr, substr_start, substr_cnt);
substr[substr_cnt] = '\0';
//
stringlist_add_end(str_s, substr);
// "+ 1" for skipping the sep char that stops "strcspn" at 2a1XF8a.
//
// If what stops "strcspn" at 2a1XF8a is null char, then "start" should
// equal (str_len + 1). This is well handled at 7fkzkrk.
start += (substr_cnt + 1);
// 7fkzkrk
if (start > str_len) {
//
assert(start == (str_len + 1));
//
break;
}
// This is the case when the last char is the sep char
else if (start == str_len) {
//
assert(str[str_len - 1] == sep);
// Allocate an empty string
char* empty_str = malloc(sizeof(char));
empty_str[0] = '\0';
// Add the last empty string.
// E.g. string_split("a|b|", '|') -> ["a", "b", ""]
stringlist_add_end(str_s, empty_str);
//
break;
}
}
}
//
void string_strip(char *str) {
//
char *end;
// Remove heading spaces.
//
// Null char is well handled by "isspace".
while (isspace(*str)) {
str++;
}
//
if (*str == '\0') {
return;
}
// Remove ending spaces
end = str + strlen(str) - 1;
while (end > str && isspace(*end)) {
end--;
}
// Set null
*(end + 1) = '\0';
}
//
void string_tolower(char* str) {
//
size_t i = 0;
for (i = 0; str[i]; i++) {
str[i] = tolower(str[i]);
}
}
//
char* string_concat_new(const char* str, const char* end) {
//
int str_len = strlen(str);
int end_len = strlen(end);
//
size_t bytes_cnt = sizeof(char) * (str_len + end_len + 1);
//
char* str_new = (char *)malloc(bytes_cnt);
//
memcpy(str_new, str, str_len);
memcpy(str_new + str_len, end, end_len);
// Set last bytes to NUL
str_new[str_len + end_len] = '\0';
//
return str_new;
}
//
BOOL string_endswith(const char* str, const char* end) {
//
int str_len = strlen(str);
int end_len = strlen(end);
//
return
// "str" is not shorter then "end"
(str_len >= end_len) &&
// Two strings' ends are equal
(!strcmp(str + str_len - end_len, end));
}
//
BOOL prog_has_ext_in(String prog, StringList* ext_s) {
//
StringNode* node = ext_s->head;
while (node) {
// If two strings are equal
if (string_endswith(prog, node->str)) {
return TRUE;
};
//
node = node->next;
}
return FALSE;
}
//
BOOL file_exists(LPCTSTR szPath) {
DWORD dwAttrib = GetFileAttributes(szPath);
return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}
//
StringList* find_exe_paths(String prog)
{
// An environment variable has a maximum size limit of 32,767 characters,
// including the null-terminating character.
char buf[32767];
// 8f1kRCu
DWORD res = GetEnvironmentVariable(TEXT("PATHEXT"), buf, 32767);
// 4fpQ2RB
// If "res" indicates error
if (res == 0) {
return NULL;
}
// 6qhHTHF
// Split into a list of extensions
//
// Freed at 9nopWXf
StringList* ext_s = stringlist_create();
string_split(ext_s, buf, ';');
//
StringNode* node;
// 2pGJrMW
// Strip
node = ext_s->head;
while (node) {
// String "node->str" is changed in-place
string_strip((char *)node->str);
//
node = node->next;
}
// 2gqeHHl
// Remove empty.
// Must be done after the stripping at 2pGJrMW.
//
// Freed at 3vUw4d9
StringList* ext_s_2 = stringlist_create();
node = ext_s->head;
while (node) {
// If is not empty string
if (node->str[0]) {
// String "node->str" is changed ownership
stringlist_add_end(ext_s_2, node->str);
// Clear old pointer
node->str = NULL;
};
//
node = node->next;
}
// 9nopWXf
stringlist_del_v2(&ext_s);
assert(!ext_s);
// 2zdGM8W
// Convert to lowercase
node = ext_s_2->head;
while (node) {
// String "node->str" is changed in-place
string_tolower((char *)node->str);
//
node = node->next;
}
// 2fT8aRB
// Uniquify
//
// Freed at 6b8UxoC
StringList* ext_s_3 = stringlist_create();
stringlist_uniq(ext_s_3, ext_s_2);
// 3vUw4d9
stringlist_del_v2(&ext_s_2);
assert(!ext_s_2);
//
StringList* dir_path_s = stringlist_create();
// 4ysaQVN
res = GetEnvironmentVariable(TEXT("PATH"), buf, sizeof buf);
// 5gGwKZL
// If "res" indicates error
if (res == 0) {
// 7bVmOKe
// Go ahead with "dir_path_s" being empty
;
}
else {
// 6mPI0lg
// Split into a list of dir paths
string_split(dir_path_s, buf, ';');
}
// 5rT49zI
// Insert empty dir path to the beginning.
//
// Empty dir handles the case that "prog" is a path, either relative or
// absolute. See code 7rO7NIN.
stringlist_add_head(dir_path_s, string_copy_new(""));
// 2klTv20
// Uniquify
//
// Freed at 6f2j5cZ
StringList* dir_path_s_2 = stringlist_create();
stringlist_uniq(dir_path_s_2, dir_path_s);
// 6f2j5cZ
stringlist_del_v2(&dir_path_s);
assert(!dir_path_s);
// 9gTU1rI
// Check if "prog" ends with one of the file extension in "ext_s".
//
// "ext_s_3" are all in lowercase, ensured at 2zdGM8W.
//
// Freed at 2aR7zCp
char* prog_lc = string_copy_new(prog);
string_tolower(prog_lc);
BOOL prog_has_ext = prog_has_ext_in(prog_lc, ext_s_3);
// 2aR7zCp
free(prog_lc);
// 6bFwhbv
//
// Freed at 8swW6Av
StringList* exe_path_s = stringlist_create();
node = dir_path_s_2->head;
while (node) {
// 7rO7NIN
// Synthesize a path
String dir_path = node->str;
String path = NULL;
// If dir path is empty string
if (!dir_path[0]) {
path = prog;
}
else {
// "PathCombine" will not writes more than MAX_PATH chars to "buf"
assert(sizeof buf >= MAX_PATH);
LPTSTR res = PathCombine(buf, dir_path, prog);
// If "res" indicates error
if (res == NULL) {
// Ignore
continue;
}
//
path = buf;
}
// 6kZa5cq
// If "prog" ends with executable file extension
if (prog_has_ext) {
// 3whKebE
if (file_exists(path)) {
// 2ffmxRF
stringlist_add_end(exe_path_s, string_copy_new(path));
}
}
// 2sJhhEV
// Assume user has omitted the file extension
StringNode* ext_node = ext_s_3->head;
while (ext_node) {
// 6k9X6GP
// Synthesize a path with one of the file extensions in PATHEXT
//
// Freed at 4vT1o9M, or changed ownership at 7dui4cD
char* path_2 = string_concat_new(path, ext_node->str);
// 6kabzQg
if (file_exists(path_2)) {
// 7dui4cD
// "path_2" is changed ownership
stringlist_add_end(exe_path_s, path_2);
}
else {
// 4vT1o9M
free(path_2);
}
//
ext_node = ext_node->next;
}
//
node = node->next;
}
// 6b8UxoC
stringlist_del_v2(&ext_s_3);
assert(!ext_s_3);
// 8swW6Av
// Uniquify
StringList* exe_path_s_2 = stringlist_create();
stringlist_uniq(exe_path_s_2, exe_path_s);
stringlist_del_v2(&exe_path_s);
assert(!exe_path_s);
// 7y3JlnS
return exe_path_s_2;
};
// 4zKrqsC
// Program entry
int main(int argc, char* argv[])
{
//
int exit_code = 0;
// 9mlJlKg
// If not exactly one command argument is given
if (argc != 2) {
// 7rOUXFo
// Print program usage
char const * const usage_txt = "Usage: aoikwinwhich PROG\n"
"\n"
"#/ PROG can be either name or path\n"
"aoikwinwhich notepad.exe\n"
"aoikwinwhich C:\\Windows\\notepad.exe\n"
"\n"
"#/ PROG can be either absolute or relative\n"
"aoikwinwhich C:\\Windows\\notepad.exe\n"
"aoikwinwhich Windows\\notepad.exe\n"
"\n"
"#/ PROG can be either with or without extension\n"
"aoikwinwhich notepad.exe\n"
"aoikwinwhich notepad\n"
"aoikwinwhich C:\\Windows\\notepad.exe\n"
"aoikwinwhich C:\\Windows\\notepad";
printf("%s", usage_txt);
// 3nqHnP7
exit_code = 1;
return exit_code;
}
//
assert(argc == 2);
// 9m5B08H
// Get executable name or path
String prog = argv[1];
// 8ulvPXM
// Find executable paths
//
// Freed at 2jUVFP0
StringList* exe_path_s = find_exe_paths(prog);
// 5fWrcaF
// If has found none
if (!exe_path_s || !exe_path_s->count) {
// 3uswpx0
exit_code = 2;
}
// If has found some
else {
// 9xPCWuS
// Print result
StringNode* node = exe_path_s->head;
while (node) {
//
printf("%s\n", node->str);
//
node = node->next;
}
// 4s1yY1b
exit_code = 0;
}
// 2jUVFP0
if (exe_path_s) {
stringlist_del_v2(&exe_path_s);
assert(!exe_path_s);
}
//
return exit_code;
}
AoikWinWhich-Ceylon
//
import ceylon.collection { LinkedList }
import java.io { File }
import java.lang { System }
import java.nio.file { Files, Paths }
shared object aoikWinWhich {
shared {String*} uniq({String*} item_s) {
value item_s_new = LinkedList<String>();
for (item in item_s) {
if (!(item in item_s_new)) {
item_s_new.add(item);
}
}
return item_s_new;
}
shared {String*} find_executable(String prog) {
// 8f1kRCu
value env_var_PATHEXT = System.getenv("PATHEXT") else "";
// 6qhHTHF
// split into a list of extensions
variable {String*} ext_s = (env_var_PATHEXT == "")
then {}
else env_var_PATHEXT.split((x) => x == (File.pathSeparator[0] else ';'));
// 2pGJrMW
// strip
ext_s = ext_s.map((x) => x.trim(' '.equals));
// 2gqeHHl
// remove empty
ext_s = ext_s.filter((x) => x != "");
// 2zdGM8W
// convert to lowercase
ext_s = ext_s.map((x) => x.lowercased);
// 2fT8aRB
// uniquify
ext_s = uniq(ext_s);
value ext_s2 = LinkedList<String>(ext_s);
// 4ysaQVN
value env_var_PATH = System.getenv("PATH") else "";
// 6mPI0lg
variable LinkedList<String> dir_path_s = (env_var_PATH == "")
then LinkedList<String>()
else LinkedList<String>(env_var_PATH.split((x) => x == (File.pathSeparator[0] else ';')));
// 5rT49zI
// insert empty dir path to the beginning
//
// Empty dir handles the case that |prog| is a path, either relative or
// absolute. See code 7rO7NIN.
dir_path_s.insert(0, "");
// 2klTv20
// uniquify
dir_path_s = LinkedList<String>(uniq(dir_path_s));
//
value prog_lc = prog.lowercased;
value prog_has_ext = ext_s2.any((ext) => prog_lc.endsWith(ext));
// 6bFwhbv
value exe_path_s = LinkedList<String>();
for (dir_path in dir_path_s) {
// 7rO7NIN
// synthesize a path with the dir and prog
value path = (dir_path == "")
then prog
else Paths.get(dir_path, prog).string;
// 6kZa5cq
// assume the path has extension, check if it is an executable
if (prog_has_ext && Files.isRegularFile(Paths.get(path))) {
exe_path_s.add(path);
}
// 2sJhhEV
// assume the path has no extension
for (ext in ext_s) {
// 6k9X6GP
// synthesize a new path with the path and the executable extension
value path_plus_ext = path + ext;
// 6kabzQg
// check if it is an executable
if (Files.isRegularFile(Paths.get(path_plus_ext))) {
exe_path_s.add(path_plus_ext);
}
}
}
// 8swW6Av
// uniquify
value exe_path_s2 = uniq(exe_path_s);
//
return exe_path_s2;
}
shared void main() {
// 9mlJlKg
// check if one cmd arg is given
if (process.arguments.size != 1) {
// 7rOUXFo
// print program usage
print("Usage: aoikwinwhich PROG");
print("");
print("#/ PROG can be either name or path");
print("aoikwinwhich notepad.exe");
print("aoikwinwhich C:\\Windows\\notepad.exe");
print("");
print("#/ PROG can be either absolute or relative");
print("aoikwinwhich C:\\Windows\\notepad.exe");
print("aoikwinwhich Windows\\notepad.exe");
print("");
print("#/ PROG can be either with or without extension");
print("aoikwinwhich notepad.exe");
print("aoikwinwhich notepad");
print("aoikwinwhich C:\\Windows\\notepad.exe");
print("aoikwinwhich C:\\Windows\\notepad");
// 3nqHnP7
return;
}
// 9m5B08H
// get name or path of a program from cmd arg
value prog = process.arguments[0] else "";
// 8ulvPXM
// find executables
value path_s = find_executable(prog);
// 5fWrcaF
// has found none, exit
if (path_s.size == 0) {
// 3uswpx0
return;
}
// 9xPCWuS
// has found some, output
value txt = "\n".join(path_s);
print(txt);
// 4s1yY1b
return;
}
}
// define a toplevel method |aoikwinwhich::main|
shared void main() {
aoikWinWhich.main();
}
AoikWinWhich-Clojure
;;
(ns aoikwinwhich)
(require '[clojure.string :refer [join]])
(require '[clojure.string :refer [split]])
(import java.io.File)
(import java.lang.System)
(import java.nio.file.Files)
(import java.nio.file.LinkOption)
(import java.nio.file.Paths)
(import java.util.LinkedList)
;;
(defn -path_make
[part_s]
(.toString (Paths/get "" (into-array part_s)))
)
(defn -file_exists
[path]
(Files/isRegularFile (Paths/get "" (into-array [path])) (make-array LinkOption 0))
)
(defn -find_executable
[prog]
(let [
;; 8f1kRCu
env_var_PATHEXT (. System getenv "PATHEXT")
;;; can be nil
;; 4ysaQVN
env_var_PATH (. System getenv "PATH")
;;; can be nil
val_sep_re (re-pattern File/pathSeparator)
]
;;
(let [
ext_s
;; 2fT8aRB
;; uniquify
(distinct
;; 2zdGM8W
;; convert to lowercase
(map #(.toLowerCase %1)
;; 2gqeHHl
;; remove empty
(filter #(not (= %1 ""))
;; 2pGJrMW
;; strip
(map #(.trim %1)
;; 6qhHTHF
;; split into a list of extensions
(if (nil? env_var_PATHEXT)
([])
(split env_var_PATHEXT val_sep_re)
)
)
)
)
)
]
;;
(let [
dir_path_s
;; 2klTv20
;; uniquify
(distinct
;; 5rT49zI
;; insert empty dir path to the beginning
;;
;; Empty dir handles the case that |prog| is a path, either relative or
;; absolute. See code 7rO7NIN.
(into [""]
;; 6mPI0lg
(if (nil? env_var_PATH)
([])
(split env_var_PATH val_sep_re)
)
)
)
]
;; 6bFwhbv
(let [
exe_path_s (LinkedList.)
prog_lower (.toLowerCase prog)
prog_has_ext
(some #(. prog_lower endsWith %1) ext_s)
]
(doseq [dir_path dir_path_s]
;; 7rO7NIN
;; synthesize a path with the dir and prog
(let [
path
(if (= dir_path "")
prog
(-path_make [dir_path prog])
)
]
;; 6kZa5cq
;; assume the path has extension, check if it is an executable
(if (and prog_has_ext (-file_exists path))
(. exe_path_s add path)
()
)
;; 2sJhhEV
;; assume the path has no extension
(doseq [ext ext_s]
;; 6k9X6GP
;; synthesize a new path with the path and the executable extension
(let [
path_plus_ext (str path ext)
]
;; 6kabzQg
;; check if it is an executable
(if (-file_exists path_plus_ext)
(. exe_path_s add path_plus_ext)
()
)
)
)
)
)
;; func res
exe_path_s
)
)
)
)
)
(defn -main
[]
;; 9mlJlKg
;; check if one cmd arg is given
(if (not (= 1 (count *command-line-args*)))
(do
;; 7rOUXFo
;; print program usage
(println "Usage: aoikwinwhich PROG")
(println "")
(println "#/ PROG can be either name or path")
(println "aoikwinwhich notepad.exe")
(println "aoikwinwhich C:\\Windows\\notepad.exe")
(println "")
(println "#/ PROG can be either absolute or relative")
(println "aoikwinwhich C:\\Windows\\notepad.exe")
(println "aoikwinwhich Windows\\notepad.exe")
(println "")
(println "#/ PROG can be either with or without extension")
(println "aoikwinwhich notepad.exe")
(println "aoikwinwhich notepad")
(println "aoikwinwhich C:\\Windows\\notepad.exe")
(println "aoikwinwhich C:\\Windows\\notepad")
;; 3nqHnP7
()
)
(do
;; 9m5B08H
;; get name or path of a program from cmd arg
(let [prog (nth *command-line-args* 0)]
;; 8ulvPXM
;; find executables
(let [path_s (-find_executable prog)]
(if (= (.size path_s) 0)
;; 5fWrcaF
;; has found none, exit
;; 3uswpx0
()
;; 9xPCWuS
;; has found some, output
(do
(println (join "\n" path_s))
;; 4s1yY1b
()
)
)
)
)
)
)
)
(-main)
AoikWinWhich-CoffeeScript
#/
'use strict'
#/
_fs = require 'fs'
_path = require 'path'
_ = require 'underscore'
#/ add func |endsWith| to String
String::endsWith ?= (s) -> s == '' or @slice(-s.length) == s
#/
is_file = (path) ->
fstat = null
try
fstat = _fs.statSync(path)
catch err
return false
return fstat && fstat.isFile()
find_executable = (prog) ->
#/ 8f1kRCu
env_var_PATHEXT = process.env.PATHEXT
## can be |undefined|
#/ 6qhHTHF
#/ split into a list of extensions
ext_s = if !env_var_PATHEXT \
then []
else env_var_PATHEXT.split(_path.delimiter)
#/ 2pGJrMW
#/ strip
ext_s = (ext.trim() for ext in ext_s)
#/ 2gqeHHl
#/ remove empty
ext_s = (ext for ext in ext_s when ext != '')
#/ 2zdGM8W
#/ convert to lowercase
ext_s = (ext.toLowerCase() for ext in ext_s)
#/ 2fT8aRB
#/ uniquify
ext_s = _.uniq(ext_s)
#/ 4ysaQVN
env_var_PATH = process.env.PATH
#// can be |undefined|
#//
#// if has value, there is an ending || in it,
#// which results in an ending empty string for the splitting at 3zVznlK
#/ 6mPI0lg
dir_path_s = if !env_var_PATH \
then []
else env_var_PATH.split(_path.delimiter)
## 3zVznlK
#/ 5rT49zI
#/ insert empty dir path to the beginning
#/
#/ Empty dir handles the case that |prog| is a path, either relative or absolute.
#/ See code 7rO7NIN.
dir_path_s.unshift('')
#/ 2klTv20
#/ uniquify
dir_path_s = _.uniq(dir_path_s)
#/ 6bFwhbv
exe_path_s = []
_.each(dir_path_s, (dir_path) ->
#/ 7rO7NIN
#/ synthesize a path with the dir and prog
path = _path.join(dir_path, prog)
#/ 6kZa5cq
#/ assume the path has extension, check if it is an executable
if _.any(ext_s, (ext) -> path.endsWith(ext))
if is_file(path)
exe_path_s.push(path)
#/ 2sJhhEV
#/ assume the path has no extension
_.each(ext_s, (ext) ->
#/ 6k9X6GP
#/ synthesize a new path with the path and the executable extension
path_plus_ext = path + ext
#/ 6kabzQg
#/ check if it is an executable
if is_file(path_plus_ext)
exe_path_s.push(path_plus_ext)
)
)
#/ 8swW6Av
#/ uniquify
exe_path_s = _.uniq(exe_path_s)
#/
return exe_path_s
println = (txt) ->
process.stdout.write(txt + '\n')
main = ->
#/ 9mlJlKg
#/ check if one cmd arg is given
arg_s = process.argv.slice(2)
if arg_s.length != 1
#/ 7rOUXFo
#/ print program usage
println 'Usage: aoikwinwhich PROG'
println ''
println '#/ PROG can be either name or path'
println 'aoikwinwhich notepad.exe'
println 'aoikwinwhich C:\\Windows\\notepad.exe'
println ''
println '#/ PROG can be either absolute or relative'
println 'aoikwinwhich C:\\Windows\\notepad.exe'
println 'aoikwinwhich Windows\\notepad.exe'
println ''
println '#/ PROG can be either with or without extension'
println 'aoikwinwhich notepad.exe'
println 'aoikwinwhich notepad'
println 'aoikwinwhich C:\\Windows\\notepad.exe'
println 'aoikwinwhich C:\\Windows\\notepad'
#/ 3nqHnP7
return
#/ 9m5B08H
#/ get name or path of a program from cmd arg
prog = arg_s[0]
#/ 8ulvPXM
#/ find executables
path_s = find_executable(prog)
#/ 5fWrcaF
#/ has found none, exit
if !path_s.length
#/ 3uswpx0
return
#/ 9xPCWuS
#/ has found some, output
txt = path_s.join('\n')
println txt
#/ 4s1yY1b
return
#/
exports.main = main
#/
if require.main == module
main()
AoikWinWhich-Cpp
//
#include "stdafx.h"
#include <iostream>
#include <string>
#include <list>
#include <set>
#include <algorithm>
#include <windows.h>
#include <Shlwapi.h>
#pragma comment(lib, "Shlwapi.lib")
//
using namespace std;
//
#ifdef _UNICODE
#define WA_COUT wcout
#define WA_STRING wstring
#else
#define WA_COUT cout
#define WA_STRING string
#endif
// Modified from http://stackoverflow.com/questions/236129/split-a-string-in-c/7408245#7408245
// --- BEG
void string_split(list<WA_STRING> &tokens, const WA_STRING &text, char sep) {
int start = 0, end = 0;
while ((end = text.find(sep, start)) != WA_STRING::npos) {
tokens.push_back(text.substr(start, end - start));
start = end + 1;
}
tokens.push_back(text.substr(start));
}
// --- END
// Modified from http://stackoverflow.com/questions/216823/whats-the-best-way-to-trim-stdstring/15649849#15649849
// --- BEG
WA_STRING string_strip(const WA_STRING& s) {
const WA_STRING& chars = TEXT(" ");
size_t begin = 0;
size_t end = s.size() - 1;
for (; begin < s.size(); begin++)
if (chars.find_first_of(s[begin]) == WA_STRING::npos)
break;
for (; end > begin; end--)
if (chars.find_first_of(s[end]) == WA_STRING::npos)
break;
return s.substr(begin, end - begin + 1);
}
// --- END
//
WA_STRING string_tolower(WA_STRING str) {
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
return str;
}
// Modified from http://stackoverflow.com/questions/874134/find-if-string-endswith-another-string-in-c/874160#874160
BOOL string_endswith(WA_STRING const &str, WA_STRING const &end) {
if (str.length() >= end.length()) {
return (0 == str.compare(str.length() - end.length(), end.length(), end));
}
else {
return false;
}
}
//
void list_strip(list<WA_STRING>& item_s) {
std::transform(item_s.begin(), item_s.end(), item_s.begin(), string_strip);
}
//
void list_remove_empty(list<WA_STRING>& item_s) {
list<WA_STRING>::iterator iter = item_s.begin();
while (iter != item_s.end()) {
// if current item is empty string
if (*iter == TEXT("")) {
iter = item_s.erase(iter);
}
else {
++iter;
}
}
}
//
void list_tolower(list<WA_STRING>& item_s) {
std::transform(item_s.begin(), item_s.end(), item_s.begin(), string_tolower);
}
// Modified from http://stackoverflow.com/questions/4885676/remove-duplicates-from-a-listint/4885787#4885787
// --- BEG
void list_uniq(list<WA_STRING>& item_s) {
list<WA_STRING>::iterator iter = item_s.begin();
set<WA_STRING> item_s_met;
while (iter != item_s.end()) {
// if current item has been met before
if (item_s_met.find(*iter) != item_s_met.end()) {
iter = item_s.erase(iter);
}
else {
item_s_met.insert(*iter);
++iter;
}
}
}
// --- END
//
BOOL prog_has_ext_in(WA_STRING prog, list<WA_STRING> ext_s) {
for (list<WA_STRING>::const_iterator iter = ext_s.begin(); iter != ext_s.end(); ++iter) {
if (string_endswith(prog, *iter)) {
return true;
}
}
return false;
}
//
BOOL file_exists(LPCTSTR szPath) {
DWORD dwAttrib = GetFileAttributes(szPath);
return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}
//
list<WA_STRING>* find_exe_paths(LPCTSTR prog) {
// An environment variable has a maximum size limit of 32,767 characters,
// including the null-terminating character.
TCHAR buf[32767];
// 8f1kRCu
DWORD res = GetEnvironmentVariable(TEXT("PATHEXT"), buf, 32767);
// 4fpQ2RB
// If "res" indicates error
if (res == 0) {
return NULL;
}
// 6qhHTHF
// Split into a list of extensions
list<WA_STRING> ext_s;
WA_STRING env_pathext(buf);
string_split(ext_s, env_pathext, ';');
// 2pGJrMW
// Strip
list_strip(ext_s);
// 2gqeHHl
// Remove empty.
// Must be done after the stripping at 2pGJrMW.
list_remove_empty(ext_s);
// 2zdGM8W
// Convert to lowercase
list_tolower(ext_s);
// 2fT8aRB
// Uniquify
list_uniq(ext_s);
//
list<WA_STRING> dir_path_s;
// 4ysaQVN
res = GetEnvironmentVariable(TEXT("PATH"), buf, sizeof buf);
// 5gGwKZL
// If "res" indicates error
if (res == 0) {
// 7bVmOKe
// Go ahead with "dir_path_s" being empty
;
}
else {
// 6mPI0lg
// Split into a list of dir paths
WA_STRING env_path(buf);
string_split(dir_path_s, env_path, ';');
}
// 5rT49zI
// Insert empty dir path to the beginning.
//
// Empty dir handles the case that "prog" is a path, either relative or
// absolute. See code 7rO7NIN.
dir_path_s.push_front(TEXT(""));
// 2klTv20
// Uniquify
list_uniq(dir_path_s);
// 9gTU1rI
// Check if "prog" ends with one of the file extension in "ext_s".
//
// "ext_s" are all in lowercase, ensured at 2zdGM8W.
BOOL prog_has_ext = prog_has_ext_in(string_tolower(prog), ext_s);
// 6bFwhbv
list<WA_STRING> *exe_path_s = new list<WA_STRING>();
for (list<WA_STRING>::const_iterator iter = dir_path_s.begin(); iter != dir_path_s.end(); ++iter) {
// 7rO7NIN
// Synthesize a path
WA_STRING dir_path = *iter;
WA_STRING path;
// If dir path is empty string
if (dir_path == TEXT("")) {
path = WA_STRING(prog);
}
else {
// "PathCombine" will not writes more than MAX_PATH chars to "buf"
assert(sizeof buf >= MAX_PATH);
LPTSTR res = PathCombine(buf, dir_path.c_str(), prog);
// If "res" indicates error
if (res == NULL) {
// Ignore
continue;
}
//
path = WA_STRING(buf);
}
// 6kZa5cq
// If "prog" ends with executable file extension
if (prog_has_ext) {
// 3whKebE
if (file_exists(path.c_str())) {
// 2ffmxRF
exe_path_s->push_back(path);
}
}
// 2sJhhEV
// Assume user has omitted the file extension
for (list<WA_STRING>::const_iterator iter = ext_s.begin(); iter != ext_s.end(); ++iter) {
// 6k9X6GP
// Synthesize a path with one of the file extensions in PATHEXT
WA_STRING ext = *iter;
WA_STRING path_2 = path + ext;
// 6kabzQg
if (file_exists(path_2.c_str())) {
exe_path_s->push_back(path_2);
}
}
}
// 8swW6Av
// Uniquify
list_uniq(*exe_path_s);
// 7y3JlnS
return exe_path_s;
}
// 4zKrqsC
// Program entry
int _tmain(int argc, _TCHAR* argv[])
{
//
int exit_code = 0;
// 9mlJlKg
// If not exactly one command argument is given
if (argc != 2) {
// 7rOUXFo
// print program usage
string usage_txt = "Usage: aoikwinwhich PROG\n"
"\n"
"#/ PROG can be either name or path\n"
"aoikwinwhich notepad.exe\n"
"aoikwinwhich C:\\Windows\\notepad.exe\n"
"\n"
"#/ PROG can be either absolute or relative\n"
"aoikwinwhich C:\\Windows\\notepad.exe\n"
"aoikwinwhich Windows\\notepad.exe\n"
"\n"
"#/ PROG can be either with or without extension\n"
"aoikwinwhich notepad.exe\n"
"aoikwinwhich notepad\n"
"aoikwinwhich C:\\Windows\\notepad.exe\n"
"aoikwinwhich C:\\Windows\\notepad";
//
cout << usage_txt << endl;
// 3nqHnP7
exit_code = 1;
return exit_code;
}
// 9m5B08H
// Get executable name or path
LPCTSTR prog = argv[1];
// 8ulvPXM
// Find executable paths
//
// Freed at 2jUVFP0
list<WA_STRING>* exe_path_s = find_exe_paths(prog);
// 5fWrcaF
// If has found none
if (!exe_path_s || !exe_path_s->size()) {
// 3uswpx0
exit_code = 2;
}
// If has found some
else {
// 9xPCWuS
// Print result
for (list<WA_STRING>::const_iterator iter = exe_path_s->begin();
iter != exe_path_s->end();
++iter) {
WA_COUT << WA_STRING(*iter) << endl;
}
// 4s1yY1b
exit_code = 0;
}
// 2jUVFP0
if (exe_path_s) {
delete(exe_path_s);
}
//
return exit_code;
}
AoikWinWhich-Cpp-CLI
//
#include "stdafx.h"
using namespace System;
using namespace System::Collections::Generic;
using namespace System::IO;
//
bool contain (List<String^>^ item_s, String^ item) {
for each (String^ itemx in item_s) {
if (itemx->Equals(item)) {
return true;
}
}
return false;
}
List<String^>^ uniq (List<String^>^ item_s) {
List<String^>^ item_s_new = gcnew List<String^>();
for each (String^ item in item_s) {
if (!contain(item_s_new, item)) {
item_s_new->Add(item);
}
}
return item_s_new;
}
List<String^>^ find_executable (String^ prog) {
// 8f1kRCu
String^ env_var_PATHEXT = Environment::GetEnvironmentVariable("PATHEXT");
/// can be nullptr
// 6qhHTHF
// split into a list of extensions
List<String^>^ ext_s = (env_var_PATHEXT == nullptr)
? gcnew List<String^>()
: gcnew List<String^>(env_var_PATHEXT->Split(Path::PathSeparator));
// 2pGJrMW
// strip
List<String^>^ ext_s_old = ext_s;
ext_s = gcnew List<String^>();
for each (String^ ext in ext_s_old) {
ext_s->Add(ext->Trim());
}
// 2gqeHHl
// remove empty
ext_s_old = ext_s;
ext_s = gcnew List<String^>();
for each (String^ ext in ext_s_old) {
if (!ext->Equals("")) {
ext_s->Add(ext);
}
}
// 2zdGM8W
// convert to lowercase
ext_s_old = ext_s;
ext_s = gcnew List<String^>();
for each (String^ ext in ext_s_old) {
ext_s->Add(ext->ToLower());
}
// 2fT8aRB
// uniquify
ext_s = uniq(ext_s);
// 4ysaQVN
String^ env_var_PATH = Environment::GetEnvironmentVariable("PATH");
/// can be nullptr
List<String^>^ dir_path_s = (env_var_PATH == nullptr)
? gcnew List<String^>()
: gcnew List<String^>(env_var_PATH->Split(Path::PathSeparator));
// 5rT49zI
// insert empty dir path to the beginning
//
// Empty dir handles the case that |prog| is a path, either relative or
// absolute. See code 7rO7NIN.
dir_path_s->Insert(0, "");
// 2klTv20
// uniquify
dir_path_s = uniq(dir_path_s);
//
String^ prog_lc = prog->ToLower();
bool prog_has_ext = false;
for each (String^ ext in ext_s) {
if (prog_lc->EndsWith(ext)) {
prog_has_ext = true;
}
}
// 6bFwhbv
List<String^>^ exe_path_s = gcnew List<String^>();
for each (String^ dir_path in dir_path_s) {
// 7rO7NIN
// synthesize a path with the dir and prog
String^ path = (dir_path->Equals(""))
? prog
: Path::Combine(dir_path, prog);
// 6kZa5cq
// assume the path has extension, check if it is an executable
if (prog_has_ext && File::Exists(path))
{
exe_path_s->Add(path);
}
// 2sJhhEV
// assume the path has no extension
for each (String^ ext in ext_s) {
// 6k9X6GP
// synthesize a new path with the path and the executable extension
String^ path_plus_ext = path + ext;
// 6kabzQg
// check if it is an executable
if (File::Exists(path_plus_ext))
{
exe_path_s->Add(path_plus_ext);
}
}
}
// 8swW6Av
// uniquify
exe_path_s = uniq(exe_path_s);
//
return exe_path_s;
}
int main(array<String ^> ^args)
{
// 9mlJlKg
if (args->Length != 1)
{
// 7rOUXFo
// print program usage
Console::WriteLine("Usage: aoikwinwhich PROG");
Console::WriteLine("");
Console::WriteLine("#/ PROG can be either name or path");
Console::WriteLine("aoikwinwhich notepad.exe");
Console::WriteLine("aoikwinwhich C:\\Windows\\notepad.exe");
Console::WriteLine("");
Console::WriteLine("#/ PROG can be either absolute or relative");
Console::WriteLine("aoikwinwhich C:\\Windows\\notepad.exe");
Console::WriteLine("aoikwinwhich Windows\\notepad.exe");
Console::WriteLine("");
Console::WriteLine("#/ PROG can be either with or without extension");
Console::WriteLine("aoikwinwhich notepad.exe");
Console::WriteLine("aoikwinwhich notepad");
Console::WriteLine("aoikwinwhich C:\\Windows\\notepad.exe");
Console::WriteLine("aoikwinwhich C:\\Windows\\notepad");
// 3nqHnP7
return 2;
}
// 9m5B08H
// get name or path of a program from cmd arg
String^ prog = args[0];
// 8ulvPXM
// find executables
List<String^>^ path_s = find_executable(prog);
// 5fWrcaF
// has found none, exit
if (path_s->Count == 0)
{
// 3uswpx0
return 1;
}
// 9xPCWuS
// has found some, output
String^ txt = String::Join("\n", path_s);
Console::WriteLine(txt);
// 4s1yY1b
return 0;
}
AoikWinWhich-CSharp
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
//
namespace AoikWinWhich
{
class AoikWinWhich
{
static List<String> find_executable(String prog)
{
// 8f1kRCu
var env_var_PATHEXT = Environment.GetEnvironmentVariable("PATHEXT");
/// can be null
// 6qhHTHF
// split into a list of extensions
var ext_s = (env_var_PATHEXT == null)
? new List<String>()
: new List<String>(env_var_PATHEXT.Split(Path.PathSeparator));
// 2pGJrMW
// strip
ext_s = ext_s.Select(x => x.Trim()).ToList();
// 2gqeHHl
// remove empty
ext_s = ext_s.Where(x => x != "").ToList();
// 2zdGM8W
// convert to lowercase
ext_s = ext_s.Select(x => x.ToLower()).ToList();
// 2fT8aRB
// uniquify
ext_s = ext_s.Distinct().ToList();
// 4ysaQVN
var env_var_PATH = Environment.GetEnvironmentVariable("PATH");
/// can be null
var dir_path_s = (env_var_PATH == null)
? new List<String>()
: new List<String>(env_var_PATH.Split(Path.PathSeparator));
// 5rT49zI
// insert empty dir path to the beginning
//
// Empty dir handles the case that |prog| is a path, either relative or
// absolute. See code 7rO7NIN.
dir_path_s.Insert(0, "");
// 2klTv20
// uniquify
dir_path_s = dir_path_s.Distinct().ToList();
//
var prog_lc = prog.ToLower();
var prog_has_ext = ext_s.Any(ext => prog_lc.EndsWith(ext));
// 6bFwhbv
var exe_path_s = new List<String>();
foreach (var dir_path in dir_path_s)
{
// 7rO7NIN
// synthesize a path with the dir and prog
var path = (dir_path == "")
? prog
: Path.Combine(dir_path, prog);
// 6kZa5cq
// assume the path has extension, check if it is an executable
if (prog_has_ext && File.Exists(path))
{
exe_path_s.Add(path);
}
// 2sJhhEV
// assume the path has no extension
foreach (var ext in ext_s)
{
// 6k9X6GP
// synthesize a new path with the path and the executable extension
var path_plus_ext = path + ext;
// 6kabzQg
// check if it is an executable
if (File.Exists(path_plus_ext))
{
exe_path_s.Add(path_plus_ext);
}
}
}
// 8swW6Av
// uniquify
exe_path_s = exe_path_s.Distinct().ToList();
//
return exe_path_s;
}
static void Main(String[] args)
{
// 9mlJlKg
if (args.Length != 1)
{
// 7rOUXFo
// print program usage
Console.WriteLine(@"Usage: aoikwinwhich PROG");
Console.WriteLine(@"");
Console.WriteLine(@"#/ PROG can be either name or path");
Console.WriteLine(@"aoikwinwhich notepad.exe");
Console.WriteLine(@"aoikwinwhich C:\Windows\notepad.exe");
Console.WriteLine(@"");
Console.WriteLine(@"#/ PROG can be either absolute or relative");
Console.WriteLine(@"aoikwinwhich C:\Windows\notepad.exe");
Console.WriteLine(@"aoikwinwhich Windows\notepad.exe");
Console.WriteLine(@"");
Console.WriteLine(@"#/ PROG can be either with or without extension");
Console.WriteLine(@"aoikwinwhich notepad.exe");
Console.WriteLine(@"aoikwinwhich notepad");
Console.WriteLine(@"aoikwinwhich C:\Windows\notepad.exe");
Console.WriteLine(@"aoikwinwhich C:\Windows\notepad");
// 3nqHnP7
return;
}
// 9m5B08H
// get name or path of a program from cmd arg
var prog = args[0];
// 8ulvPXM
// find executables
var path_s = find_executable(prog);
// 5fWrcaF
// has found none, exit
if (path_s.Count == 0)
{
// 3uswpx0
return;
}
// 9xPCWuS
// has found some, output
var txt = String.Join("\n", path_s);
Console.WriteLine(txt);
// 4s1yY1b
return;
}
}
}
AoikWinWhich-D
//
module aoikwinwhich;
import std.algorithm: any;
import std.algorithm: endsWith;
import std.algorithm: map;
import std.algorithm: filter;
import std.array : appender;
import std.array : array;
import std.array : join;
import std.array : split;
import std.file : FileException;
import std.file : isFile;
import std.path : buildPath;
import std.path : pathSeparator;
import std.process: env = environment;
import std.stdio : writeln;
import std.string : toLower;
//
bool contain(string[] item_s, string item) {
foreach (_item; item_s) {
if (_item == item) {
return true;
}
}
return false;
}
string[] uniq(string[] item_s) {
auto item_s_new = appender!(string[]);
foreach (item; item_s) {
if (!contain(item_s_new.data, item)) {
item_s_new.put(item);
}
}
return item_s_new.data;
}
bool file_exists(string path) {
auto path_is_file = false;
try {
path_is_file = path.isFile();
} catch (FileException) {}
return path_is_file;
}
string[] find_executable(string prog) {
// 8f1kRCu
auto env_var_PATHEXT = env.get(`PATHEXT`);
/// can be ""
// 6qhHTHF
// split into a list of extensions
auto ext_s = (env_var_PATHEXT == "")
? []
: env_var_PATHEXT.split(pathSeparator);
// 2pGJrMW
// strip
ext_s = array(ext_s.map!(x => x));
// 2gqeHHl
// remove empty
ext_s = array(ext_s.filter!(x => x != ""));
// 2zdGM8W
// convert to lowercase
ext_s = array(ext_s.map!(x => x.toLower()));
// 2fT8aRB
// uniquify
ext_s = uniq(ext_s);
// 4ysaQVN
auto env_var_PATH = env.get(`PATH`);
/// can be ""
// 6mPI0lg
auto dir_path_s = (env_var_PATH == "")
? []
: env_var_PATH.split(pathSeparator);
// 5rT49zI
// insert empty dir path to the beginning
//
// Empty dir handles the case that |prog| is a path, either relative or
// absolute. See code 7rO7NIN.
dir_path_s = [""] ~ dir_path_s;
// 2klTv20
// uniquify
dir_path_s = uniq(dir_path_s);
//
auto prog_lower = prog.toLower();
auto prog_has_ext = ext_s.any!(x => prog_lower.endsWith(x));
// 6bFwhbv
auto exe_path_s = appender!(string[]);
foreach (dir_path; dir_path_s) {
// 7rO7NIN
// synthesize a path with the dir and prog
auto path = (dir_path == "")
? prog
: buildPath(dir_path, prog);
// 6kZa5cq
// assume the path has extension, check if it is an executable
if (prog_has_ext && file_exists(path)) {
exe_path_s.put(path);
}
// 2sJhhEV
// assume the path has no extension
foreach (ext; ext_s) {
// 6k9X6GP
// synthesize a new path with the path and the executable extension
auto path_plus_ext = path ~ ext;
// 6kabzQg
// check if it is an executable
if (file_exists(path_plus_ext)) {
exe_path_s.put(path_plus_ext);
}
}
}
// 8swW6Av
// uniquify
auto exe_path_s_uniq = uniq(exe_path_s.data);
//
return exe_path_s_uniq;
}
void main(string[] args)
{
// 9mlJlKg
// check if one cmd arg is given
if (args.length != 2) {
// 7rOUXFo
// print program usage
writeln(`Usage: aoikwinwhich PROG`);
writeln(``);
writeln(`#/ PROG can be either name or path`);
writeln(`aoikwinwhich notepad.exe`);
writeln(`aoikwinwhich C:\Windows\notepad.exe`);
writeln(``);
writeln(`#/ PROG can be either absolute or relative`);
writeln(`aoikwinwhich C:\Windows\notepad.exe`);
writeln(`aoikwinwhich Windows\notepad.exe`);
writeln(``);
writeln(`#/ PROG can be either with or without extension`);
writeln(`aoikwinwhich notepad.exe`);
writeln(`aoikwinwhich notepad`);
writeln(`aoikwinwhich C:\Windows\notepad.exe`);
writeln(`aoikwinwhich C:\Windows\notepad`);
// 3nqHnP7
return;
}
// 9m5B08H
// get name or path of a program from cmd arg
auto prog = args[1];
// 8ulvPXM
// find executables
auto path_s = find_executable(prog);
// 5fWrcaF
// has found none, exit
if (path_s.length == 0) {
// 3uswpx0
return;
}
// 9xPCWuS
// has found some, output
auto txt = array(path_s).join("\n");
writeln(txt);
// 4s1yY1b
return;
}
AoikWinWhich-Dart
//
import 'dart:io' show File;
import 'dart:io' show Platform;
//
List<String> list_uniq(List item_s) {
var item_s_uniq = [];
for (var item in item_s) {
if (!item_s_uniq.contains(item)) {
item_s_uniq.add(item);
}
}
return item_s_uniq;
}
List<String> find_executable(String prog) {
// 8f1kRCu
var env_var_PATHEXT = Platform.environment['PATHEXT'];
/// can be null
// 6qhHTHF
// split into a list of extensions
var sep = ';';
var ext_s = (env_var_PATHEXT == null) ? [] : env_var_PATHEXT.split(sep);
// 2pGJrMW
// strip
ext_s = ext_s.map((x) => x.trim());
/// result is iterable
// 2gqeHHl
// remove empty
ext_s = ext_s.where((x) => x != '');
/// result is iterable
// 2zdGM8W
// convert to lowercase
ext_s = ext_s.map((x) => x.toLowerCase());
/// result is iterable
// 2fT8aRB
// uniquify
ext_s = list_uniq(ext_s);
/// result is list
// 4ysaQVN
var env_var_PATH = Platform.environment['PATH'];
/// can be null
// 6mPI0lg
var dir_path_s = (env_var_PATH == null) ? [] : env_var_PATH.split(sep);
// 5rT49zI
// insert empty dir path to the beginning
//
// Empty dir handles the case that |prog| is a path, either relative or
// absolute. See code 7rO7NIN.
dir_path_s.insert(0, '');
// 2klTv20
// uniquify
dir_path_s = list_uniq(dir_path_s);
//
var prog_has_ext = ext_s.any((x) => prog.endsWith(x));
// 6bFwhbv
var exe_path_s = [];
for (var dir_path in dir_path_s) {
// 7rO7NIN
// synthesize a path with the dir and prog
var path = (dir_path == '')
? prog
: dir_path + '\\' + prog;
// 6kZa5cq
// assume the path has extension, check if it is an executable
if (prog_has_ext && new File(path).existsSync()) {
exe_path_s.add(path);
}
// 2sJhhEV
// assume the path has no extension
for (var ext in ext_s) {
// 6k9X6GP
// synthesize a new path with the path and the executable extension
var path_plus_ext = path + ext;
// 6kabzQg
// check if it is an executable
if (new File(path_plus_ext).existsSync()) {
exe_path_s.add(path_plus_ext);
}
}
}
// 8swW6Av
// uniquify
exe_path_s = list_uniq(exe_path_s);
//
return exe_path_s;
}
void main(List<String> args) {
// 9mlJlKg
if (args.length != 1) {
// 7rOUXFo
// print program usage
print(r'Usage: aoikwinwhich PROG');
print('');
print(r'#/ PROG can be either name or path');
print(r'aoikwinwhich notepad.exe');
print(r'aoikwinwhich C:\Windows\notepad.exe');
print('');
print(r'#/ PROG can be either absolute or relative');
print(r'aoikwinwhich C:\Windows\notepad.exe');
print(r'aoikwinwhich Windows\notepad.exe');
print('');
print(r'#/ PROG can be either with or without extension');
print(r'aoikwinwhich notepad.exe');
print(r'aoikwinwhich notepad');
print(r'aoikwinwhich C:\Windows\notepad.exe');
print(r'aoikwinwhich C:\Windows\notepad');
// 3nqHnP7
return;
}
// 9m5B08H
// get name or path of a program from cmd arg
var prog = args[0];
// 8ulvPXM
// find executables
var path_s = find_executable(prog);
// 5fWrcaF
// has found none, exit
if (path_s.length == 0) {
// 3uswpx0
return;
}
// 9xPCWuS
// has found some, output
var txt = path_s.reduce((a, b) => a + '\n' + b);
print(txt);
// 4s1yY1b
return;
}
AoikWinWhich-Eiffel
--
class
AOIKWINWHICH
create
make
feature {NONE} -- Create
make
local
exc: EXCEPTIONS
do
create exc
exc.die (main)
end
feature {NONE} -- Main
-- 4zKrqsC
-- Program entry
main: INTEGER
local
args: ARGUMENTS_32
prog: STRING_32
exe_path_s: LIST [STRING_32]
do
--
create args
-- 9mlJlKg
-- If not exactly one command argument is given
if args.argument_count /~ 1 then
-- 7rOUXFo
-- Print program usage
print ("[
Usage: aoikwinwhich PROG
#/ PROG can be either name or path
aoikwinwhich notepad.exe
aoikwinwhich C:\Windows\notepad.exe
#/ PROG can be either absolute or relative
aoikwinwhich C:\Windows\notepad.exe
aoikwinwhich Windows\notepad.exe
#/ PROG can be either with or without extension
aoikwinwhich notepad.exe
aoikwinwhich notepad
aoikwinwhich C:\Windows\notepad.exe
aoikwinwhich C:\Windows\notepad
]")
-- 3nqHnP7
-- Exit
RESULT := 1
else
-- 9m5B08H
-- Get executable name or path
prog := args.argument (1)
-- 8ulvPXM
-- Find executable paths
exe_path_s := find_exe_paths (prog)
-- 5fWrcaF
-- If has found none
if exe_path_s.count = 0 then
-- 3uswpx0
-- Exit
RESULT := 2
else
-- If has found some
-- 9xPCWuS
-- Print result
across
exe_path_s as exe_path_i
loop
print (exe_path_i.item + "%N")
end
-- 4s1yY1b
-- Exit
RESULT := 0
end
end
end
feature {NONE}
--
proc_lc: STRING_32
-- "lc" means lowercase.
-- Initialized at 6pyGU6b, used at 2t8XU4N.
-- Eiffel's agent function can not access function arguments and local variables,
-- so have to use an instance field.
--
find_exe_paths (prog: STRING_32): LIST [STRING_32]
local
env: EXECUTION_ENVIRONMENT
env_pathext: detachable STRING_32
env_path: detachable STRING_32
ext_s: LIST [STRING_32]
dir_path_s: LINKED_LIST [STRING_32]
prog_has_ext: BOOLEAN
exe_path_s: LINKED_LIST [STRING_32]
path: STRING_32
path_2: STRING_32
file: PLAIN_TEXT_FILE
do
--
create env
-- 6pyGU6b
proc_lc := prog.as_lower
-- 8f1kRCu
env_pathext := env.item ("PATHEXT")
-- 4fpQ2RB
if env_pathext = Void then
-- 9dqlPRg
-- Return
Result := create {LINKED_LIST [STRING_32]}.make
else
-- 6qhHTHF
-- Split into a list of extensions
ext_s := env_pathext.split (';')
-- 2pGJrMW
-- Strip
across
ext_s as ext_i
loop
-- Mutate the string
ext_i.item.left_adjust
ext_i.item.right_adjust
end
-- 2gqeHHl
-- Remove empty.
-- Must be done after the stripping at 2pGJrMW.
ext_s := list_filter (ext_s, (agent (ext: STRING_32): BOOLEAN
do
Result := ext /= ""
end))
-- 2zdGM8W
-- Convert to lowercase
ext_s.do_all ((agent (ext: STRING_32)
do
-- Mutate the string
ext.to_lower
end))
-- 2fT8aRB
-- Uniquify
ext_s := list_uniq (ext_s)
-- 4ysaQVN
env_path := env.item ("PATH")
-- 5gGwKZL
if env_path = Void then
-- 7bVmOKe
-- Go ahead with "dir_path_s" being empty
dir_path_s := create {LINKED_LIST [STRING_32]}.make
else
-- 6mPI0lg
-- Split into a list of dir paths
dir_path_s := list_to_linked_list (env_path.split (';'))
end
-- 5rT49zI
-- Insert empty dir path to the beginning.
--
-- Empty dir handles the case that "prog" is not a short name,
-- either relative or absolute. See code 7rO7NIN.
dir_path_s.start
dir_path_s.put_left ("")
-- 2klTv20
-- Uniquify
dir_path_s := list_uniq (dir_path_s)
-- 9gTU1rI
-- Check if "prog" ends with one of the file extension in "ext_s".
prog_has_ext := ext_s.there_exists ((agent (ext: STRING_32): BOOLEAN
do
-- 2t8XU4N
Result := proc_lc.ends_with (ext)
end))
-- 6bFwhbv
create exe_path_s.make
across
dir_path_s as dir_path_i
loop
-- 7rO7NIN
-- Synthesize a path
if dir_path_i.item.is_equal ("") then
path := prog
else
path := dir_path_i.item + "\" + prog
end
--
create file.make_with_name (path)
-- 6kZa5cq
-- If "prog" ends with executable file extension
if prog_has_ext then
-- 3whKebE
if file.access_exists then
-- 2ffmxRF
exe_path_s.finish
exe_path_s.put_right (path)
end
end
-- 2sJhhEV
-- Assume user has omitted the file extension
across
ext_s as ext_i
loop
-- 6k9X6GP
-- Synthesize a path with one of the file extensions in PATHEXT
path_2 := path + ext_i.item
create file.make_with_name (path_2)
-- 6kabzQg
if file.access_exists then
-- 7dui4cD
exe_path_s.finish
exe_path_s.put_right (path_2)
end
end
end
-- 8swW6Av
-- Uniquify
exe_path_s := list_uniq (exe_path_s)
-- 7y3JlnS
Result := exe_path_s
end
end
feature {NONE} -- List util
--
list_filter (item_s: LIST [STRING_32]; predicate: FUNCTION [ANY, TUPLE [STRING_32], BOOLEAN]): LIST [STRING_32]
local
res: LINKED_LIST [STRING_32]
do
--
create res.make
--
across
item_s as i
loop
if predicate.item (i.item) then
res.finish
res.put_right (i.item)
end
end
--
Result := res
end
--
list_has_item (item_s: LIST [STRING_32]; item: STRING_32): BOOLEAN
-- Comparison is by value equality using "STRING_32.is_equal".
do
from
RESULT := false
item_s.start
until
item_s.exhausted
loop
if item_s.item.is_equal (item) then
RESULT := true
item_s.finish
end
item_s.forth
end
end
--
list_uniq (item_s: LIST [STRING_32]): LINKED_LIST [STRING_32]
local
item_s_uniq: LINKED_LIST [STRING_32]
do
--
create item_s_uniq.make
--
across
item_s as item_i
loop
-- `item_s_uniq.has(cur.item)` not works
if not list_has_item (item_s_uniq, item_i.item) then
item_s_uniq.finish
item_s_uniq.put_right (item_i.item)
end
end
--
Result := item_s_uniq
end
--
list_to_linked_list (item_s: LIST [STRING_32]): LINKED_LIST [STRING_32]
do
--
create Result.make
--
across
item_s as item_i
loop
Result.finish
Result.put_right (item_i.item)
end
end
end
AoikWinWhich-Erlang
%%
uniq(Item_s) ->
lists:foldl(
fun(Item, Acc) ->
ItemExists = lists:member(Item, Acc),
if ItemExists ->
Acc
;true ->
lists:append(Acc, [Item])
end
end, [], Item_s).
find_executale(Prog) ->
%% 8f1kRCu
EnvPATHENV = os:getenv("PATHEXT"),
%%% can be false
%% 6qhHTHF
%% split into a list of extensions
Ext_s =
if EnvPATHENV == false ->
[]
;true ->
string:tokens(EnvPATHENV, ";")
end,
%% 2pGJrMW
%% strip
Ext_s2 = lists:map(fun(X) -> string:strip(X) end, Ext_s),
%% 2gqeHHl
%% remove empty
Ext_s3 = lists:filter(fun(X) -> X =/= "" end, Ext_s2),
%% 2zdGM8W
%% convert to lowercase
Ext_s4 = lists:map(fun(X) -> string:to_lower(X) end, Ext_s3),
%% 2fT8aRB
%% uniquify
Ext_s5 = gb_sets:to_list(gb_sets:from_list(Ext_s4)),
%% 4ysaQVN
EnvPATH = os:getenv("PATH"),
%%% can be false
%% 6mPI0lg
Dir_s =
if EnvPATH == false ->
[]
;true ->
string:tokens(EnvPATH, ";")
end,
%% 5rT49zI
%% insert empty dir path to the beginning
%%
%% Empty dir handles the case that |prog| is a path, either relative or
%% absolute. See code 7rO7NIN.
Dir_s2 = ["" | Dir_s],
%% 2klTv20
%% uniquify
Dir_s3 = uniq(Dir_s2),
%%
ProgLc = string:to_lower(Prog),
ProgHasExt = lists:any(fun(Ext) -> lists:suffix(Ext, ProgLc) end, Ext_s5),
%% 6bFwhbv
Exe_path_s_res = lists:foldl(
fun(Dir, Acc) ->
%% 7rO7NIN
%% synthesize a path with the dir and prog
Path =
if Dir == "" ->
Prog
;true ->
string:join([Dir, "\\" ,Prog], "")
end,
%% 6kZa5cq
%% assume the path has extension, check if it is an executable
PathExists = filelib:is_regular(Path),
if ProgHasExt andalso PathExists ->
Exe_path_s = [Path]
;true ->
Exe_path_s = []
end,
%% 2sJhhEV
%% assume the path has no extension
Exe_path_s2 = [
%% 6k9X6GP
%% synthesize a new path with the path and the executable extension
string:concat(Path, Ext) ||
Ext <- Ext_s5,
%% 6kabzQg
%% check if it is an executable
filelib:is_regular(string:concat(Path, Ext))
],
%% New Acc result
lists:append([Acc, Exe_path_s, Exe_path_s2])
end, [], Dir_s3),
%% 8swW6Av
%% uniquify
Exe_path_s_res2 = uniq(Exe_path_s_res),
%%
Exe_path_s_res2.
println(Str) ->
io:format("~s~n", [Str]).
main(Args) ->
%% 9mlJlKg
if length(Args) =/= 1 ->
%% 7rOUXFo
%% print program usage
println("Usage: aoikwinwhich PROG"),
println(""),
println("#/ PROG can be either name or path"),
println("aoikwinwhich notepad.exe"),
println("aoikwinwhich C:\\Windows\\notepad.exe"),
println(""),
println("#/ PROG can be either absolute or relative"),
println("aoikwinwhich C:\\Windows\\notepad.exe"),
println("aoikwinwhich Windows\\notepad.exe"),
println(""),
println("#/ PROG can be either with or without extension"),
println("aoikwinwhich notepad.exe"),
println("aoikwinwhich notepad"),
println("aoikwinwhich C:\\Windows\\notepad.exe"),
println("aoikwinwhich C:\\Windows\\notepad"),
%% 3nqHnP7
noop
;true ->
%% 9m5B08H
%% get name or path of a program from cmd arg
Prog = lists:nth(1, Args),
%% 8ulvPXM
%% find executables
Path_s = find_executale(Prog),
%% 5fWrcaF
%% has found none, exit
if length(Path_s) == 0 ->
%% 3uswpx0
noop
;true ->
%% 9xPCWuS
%% has found some, output
Txt = string:join(Path_s, "\n"),
println(Txt),
%% 4s1yY1b
noop
end
end.
AoikWinWhich-FSharp
//
namespace AoikWinWhich
type Console = System.Console
type Environment = System.Environment
type File = System.IO.File
type Path = System.IO.Path
type String = System.String
//
module AoikWinWhich =
let find_executable (prog:string) =
// 8f1kRCu
let env_var_PATHEXT = Environment.GetEnvironmentVariable("PATHEXT")
/// can be null
// 6qhHTHF
// split into a list of extensions
let ext_s =
if env_var_PATHEXT = null then
[]
else
env_var_PATHEXT.Split(Path.PathSeparator) |> Array.toList
// 2pGJrMW
// strip
let ext_s = ext_s |> List.map (fun x -> x.Trim())
// 2gqeHHl
// remove empty
let ext_s = ext_s |> List.filter (fun x -> x <> "")
// 2zdGM8W
// convert to lowercase
let ext_s = ext_s |> List.map (fun x -> x.ToLower())
// 2fT8aRB
// uniquify
let ext_s = ext_s |> Seq.distinct |> Seq.toList
// 4ysaQVN
let env_var_PATH = Environment.GetEnvironmentVariable("PATH")
/// can be null
let dir_path_s =
if env_var_PATH = null then
[]
else
env_var_PATH.Split(Path.PathSeparator) |> Array.toList
// 5rT49zI
// insert empty dir path to the beginning
//
// Empty dir handles the case that |prog| is a path, either relative or
// absolute. See code 7rO7NIN.
let dir_path_s = "" :: dir_path_s
// 2klTv20
// uniquify
let dir_path_s = dir_path_s |> Seq.distinct |> Seq.toList
//
let prog_lc = prog.ToLower()
let prog_has_ext = ext_s |> List.exists (fun ext -> prog_lc.EndsWith(ext))
// 6bFwhbv
let mutable exe_path_s = []
for dir_path in dir_path_s do
// 7rO7NIN
// synthesize a path with the dir and prog
let path =
if dir_path = "" then
prog
else
Path.Combine(dir_path, prog)
// 6kZa5cq
// assume the path has extension, check if it is an executable
if prog_has_ext && File.Exists(path) then
exe_path_s <- path :: exe_path_s
()
// 2sJhhEV
// assume the path has no extension
for ext in ext_s do
// 6k9X6GP
// synthesize a new path with the path and the executable extension
let path_plus_ext = path + ext
// 6kabzQg
// check if it is an executable
if File.Exists(path_plus_ext) then
exe_path_s <- path_plus_ext :: exe_path_s
()
// reverse
let exe_path_s = exe_path_s |> List.rev
// 8swW6Av
// uniquify
let exe_path_s = exe_path_s |> Seq.distinct |> Seq.toList
// return
exe_path_s
[<EntryPoint>]
let main args =
// 9mlJlKg
let args_len = Array.length args
if args_len <> 1 then
// 7rOUXFo
// print program usage
Console.WriteLine(@"Usage: aoikwinwhich PROG")
Console.WriteLine(@"")
Console.WriteLine(@"#/ PROG can be either name or path")
Console.WriteLine(@"aoikwinwhich notepad.exe")
Console.WriteLine(@"aoikwinwhich C:\Windows\notepad.exe")
Console.WriteLine(@"")
Console.WriteLine(@"#/ PROG can be either absolute or relative")
Console.WriteLine(@"aoikwinwhich C:\Windows\notepad.exe")
Console.WriteLine(@"aoikwinwhich Windows\notepad.exe")
Console.WriteLine(@"")
Console.WriteLine(@"#/ PROG can be either with or without extension")
Console.WriteLine(@"aoikwinwhich notepad.exe")
Console.WriteLine(@"aoikwinwhich notepad")
Console.WriteLine(@"aoikwinwhich C:\Windows\notepad.exe")
Console.WriteLine(@"aoikwinwhich C:\Windows\notepad")
// 3nqHnP7
2
else
// 9m5B08H
// get name or path of a program from cmd arg
let prog = args.[0]
// 8ulvPXM
// find executables
let path_s = find_executable(prog)
//
if path_s.Length = 0 then
// 5fWrcaF
// has found none, exit
// 3uswpx0
1
else
// 9xPCWuS
// has found some, output
let txt = String.Join("\n", path_s)
Console.WriteLine(txt)
// 4s1yY1b
0
AoikWinWhich-Go
package main
import "fmt"
import "os"
import "strings"
type strtostr func(string) string
type strtobool func(string) bool
func mapto(item_s []string, f strtostr) []string {
item_s_new := []string{}
for _, item := range item_s {
item_new := f(item)
item_s_new = append(item_s_new, item_new)
}
return item_s_new
}
func filter(item_s []string, f strtobool) []string {
item_s_new := []string{}
for _, item := range item_s {
if f(item) {
item_s_new = append(item_s_new, item)
}
}
return item_s_new
}
func any(item_s []string, f strtobool) bool {
for _, item := range item_s {
if f(item) {
return true
}
}
return false
}
func contain(item_s []string, item string) bool {
for _, x := range item_s {
if x == item {
return true
}
}
return false
}
func append_uniq(item_s []string, item string) []string {
if contain(item_s, item) {
return item_s
} else {
return append(item_s, item)
}
}
func uniq(item_s []string) []string {
item_s_new := []string{}
for _, item := range item_s {
item_s_new = append_uniq(item_s_new, item)
}
return item_s_new;
}
// Modified from |http://stackoverflow.com/a/12527546|.
// ---BEG
func file_exists(path string) bool {
_, err := os.Stat(path)
if err != nil {
if os.IsNotExist(err) {
return false
}
}
return true
}
// ---END
func find_executable(prog string) []string {
// 8f1kRCu
env_var_PATHEXT := os.Getenv("PATHEXT")
/// can be ""
// 6qhHTHF
// split into a list of extensions
val_sep := string(os.PathListSeparator)
var ext_s []string = nil
if env_var_PATHEXT == "" {
ext_s = []string{}
} else {
ext_s = strings.Split(env_var_PATHEXT, val_sep)
}
// 2pGJrMW
// strip
ext_s = mapto(ext_s, func(x string) string {
return strings.TrimSpace(x)
})
// 2gqeHHl
// remove empty
ext_s = filter(ext_s, func(x string) bool {
return x != ""
})
// 2zdGM8W
// convert to lowercase
ext_s = mapto(ext_s, func(x string) string {
return strings.ToLower(x)
})
// 2fT8aRB
// uniquify
ext_s = uniq(ext_s);
// 4ysaQVN
env_var_PATH := os.Getenv("PATH")
/// can be ""
// 6mPI0lg
var dir_path_s []string = nil
if env_var_PATH == "" {
dir_path_s = []string{}
} else {
dir_path_s = strings.Split(env_var_PATH, val_sep)
}
// 5rT49zI
// insert empty dir path to the beginning
//
// Empty dir handles the case that |prog| is a path, either relative or
// absolute. See code 7rO7NIN.
dir_path_s = append([]string{""}, dir_path_s...)
// 2klTv20
// uniquify
dir_path_s = uniq(dir_path_s)
//
prog_lower := strings.ToLower(prog)
prog_has_ext := any(ext_s, func(x string) bool {
return strings.HasSuffix(prog_lower, x)
})
// 6bFwhbv
path_sep := string(os.PathSeparator)
exe_path_s := []string{}
for _, dir_path := range dir_path_s {
// 7rO7NIN
// synthesize a path with the dir and prog
path := ""
if dir_path == "" {
path = prog
} else {
path = dir_path + path_sep + prog
}
// 6kZa5cq
// assume the path has extension, check if it is an executable
if prog_has_ext && file_exists(path) {
exe_path_s = append(exe_path_s, path)
}
// 2sJhhEV
// assume the path has no extension
for _, ext := range ext_s {
// 6k9X6GP
// synthesize a new path with the path and the executable extension
path_plus_ext := path + ext
// 6kabzQg
// check if it is an executable
if file_exists(path_plus_ext) {
exe_path_s = append(exe_path_s, path_plus_ext)
}
}
}
// 8swW6Av
// uniquify
exe_path_s = uniq(exe_path_s);
//
return exe_path_s
}
func main() {
//
println := fmt.Println
// 9mlJlKg
// check if one cmd arg is given
args := os.Args[1:]
if (len(args) != 1) {
// 7rOUXFo
// print program usage
println(`Usage: aoikwinwhich PROG`);
println(``);
println(`#/ PROG can be either name or path`);
println(`aoikwinwhich notepad.exe`);
println(`aoikwinwhich C:\Windows\notepad.exe`);
println(``);
println(`#/ PROG can be either absolute or relative`);
println(`aoikwinwhich C:\Windows\notepad.exe`);
println(`aoikwinwhich Windows\notepad.exe`);
println(``);
println(`#/ PROG can be either with or without extension`);
println(`aoikwinwhich notepad.exe`);
println(`aoikwinwhich notepad`);
println(`aoikwinwhich C:\Windows\notepad.exe`);
println(`aoikwinwhich C:\Windows\notepad`);
// 3nqHnP7
return;
}
// 9m5B08H
// get name or path of a program from cmd arg
prog := args[0]
// 8ulvPXM
// find executables
path_s := find_executable(prog);
// 5fWrcaF
// has found none, exit
if (len(path_s) == 0) {
// 3uswpx0
return;
}
// 9xPCWuS
// has found some, output
txt := strings.Join(path_s, "\n")
println(txt)
// 4s1yY1b
return;
}
AoikWinWhich-Groovy
//
package aoikwinwhich
import java.io.File
import java.nio.file.Files
import java.nio.file.Paths
def find_executable(prog) {
// 8f1kRCu
def env_var_PATHEXT = System.getenv("PATHEXT")
/// can be null
// 6qhHTHF
// split into a list of extensions
def ext_s = (env_var_PATHEXT == null) ? [] :
env_var_PATHEXT.split(File.pathSeparator).toList()
// 2pGJrMW
// strip
ext_s = ext_s.collect({it.trim()})
// 2gqeHHl
// remove empty
ext_s = ext_s.grep({!it.equals("")})
// 2zdGM8W
// convert to lowercase
ext_s = ext_s.collect({it.toLowerCase()})
// 2fT8aRB
// uniquify
ext_s.unique()
// 4ysaQVN
def env_var_PATH = System.getenv("PATH")
/// can be null
// 6mPI0lg
def dir_path_s = (env_var_PATH == null) ? [] :
env_var_PATH.split(File.pathSeparator).toList()
// 5rT49zI
// insert empty dir path to the beginning
//
// Empty dir handles the case that |prog| is a path, either relative or
// absolute. See code 7rO7NIN.
dir_path_s.add(0, "")
// 2klTv20
// uniquify
dir_path_s.unique()
/// LinkedHashSet keeps the original order.
// 6bFwhbv
def exe_path_s = []
for (dir_path in dir_path_s) {
// 7rO7NIN
// synthesize a path with the dir and prog
def path = dir_path.equals("") ? prog :
Paths.get(dir_path, prog).toString()
// 6kZa5cq
// assume the path has extension, check if it is an executable
if (ext_s.any({path.endsWith(it)})) {
if (Files.isRegularFile(Paths.get(path))) {
exe_path_s.add(path)
}
}
// 2sJhhEV
// assume the path has no extension
for (ext in ext_s) {
// 6k9X6GP
// synthesize a new path with the path and the executable extension
def path_plus_ext = path + ext
// 6kabzQg
// check if it is an executable
if (Files.isRegularFile(Paths.get(path_plus_ext))) {
exe_path_s.add(path_plus_ext)
}
}
}
//
return exe_path_s
}
def main2(args) {
// 9mlJlKg
// check if one cmd arg is given
if (args.length != 1) {
// 7rOUXFo
// print program usage
println(/Usage: aoikwinwhich PROG/)
println("")
println(/#\/ PROG can be either name or path/)
println(/aoikwinwhich notepad.exe/)
println(/aoikwinwhich C:\Windows\notepad.exe/)
println("")
println(/#\/ PROG can be either absolute or relative/)
println(/aoikwinwhich C:\Windows\notepad.exe/)
println(/aoikwinwhich Windows\\notepad.exe/)
println("")
println(/#\/ PROG can be either with or without extension/)
println(/aoikwinwhich notepad.exe/)
println(/aoikwinwhich notepad/)
println(/aoikwinwhich C:\Windows\notepad.exe/)
println(/aoikwinwhich C:\Windows\notepad/)
// 3nqHnP7
return
}
// 9m5B08H
// get name or path of a program from cmd arg
def prog = args[0]
// 8ulvPXM
// find executables
def path_s = find_executable(prog)
// 5fWrcaF
// has found none, exit
if (path_s.size() == 0) {
// 3uswpx0
return
}
// 9xPCWuS
// has found some, output
def txt = path_s.join("\n")
println(txt)
//
return
}
//
main2(args)
/// |args| is func arg of the wrapping |main| func auto created by Groovy.
AoikWinWhich-Haskell
--
import Control.Monad
import Control.Exception
import System.Directory (doesFileExist)
import System.Environment
import System.Exit
import qualified Data.Text as T
import qualified Data.List as List
--
iff :: Bool -> a -> a -> a
iff True x _ = x
iff False _ y = y
--
strings_join :: String -> [String] -> String
strings_join delim [] = ""
strings_join delim (x:[]) = x
strings_join delim (x:xs) = x ++ delim ++ (strings_join delim xs)
--
texts_uniq :: [T.Text] -> [T.Text]
texts_uniq [] = []
texts_uniq (x:xs) =
let xs_uniq = (texts_uniq xs)
in
iff (x `elem` xs_uniq)
(xs_uniq)
([x] ++ xs_uniq)
--
getEnvOrEmpty :: String -> IO String
getEnvOrEmpty name =
getEnv name `catch`
-- "(e :: IOException)" is for hinting exception type
(\e -> let _ = (e :: IOException) in return "")
--
find_exe_paths :: String -> IO [String]
find_exe_paths prog =
do
-- 8f1kRCu
env_pathext <- getEnvOrEmpty "PATHEXT"
-- 4fpQ2RB
iff (env_pathext == "")
-- then
-- 9dqlPRg
(return [])
-- else
(do
-- 6qhHTHF
-- Split into a list of extensions
let ext_s = T.splitOn (T.pack ";") (T.pack env_pathext)
-- 2pGJrMW
-- Strip
let ext_s_2 = map T.strip ext_s
-- 2gqeHHl
-- Remove empty
let ext_s_3 = filter (\x -> x /= (T.pack "")) ext_s_2
-- 2zdGM8W
-- Convert to lowercase
let ext_s_4 = map T.toLower ext_s_3
-- 2fT8aRB
-- Uniquify
let ext_s_5 = texts_uniq ext_s_4
-- 4ysaQVN
env_path <- getEnvOrEmpty "PATH"
-- 5gGwKZL
let dir_path_s = iff (env_path == "")
-- then
-- 7bVmOKe
-- Go ahead with "dir_path_s" being empty
[]
-- else
-- 6mPI0lg
-- Split into a list of paths
(T.splitOn (T.pack ";") (T.pack env_path))
-- 5rT49zI
-- Insert empty dir path to the beginning.
--
-- Empty dir handles the case that "prog" is a path, either
-- relative or absolute. See code 7rO7NIN.
let dir_path_s2 = [T.pack ""] ++ dir_path_s
-- 2klTv20
-- Uniquify
let dir_path_s3 = texts_uniq dir_path_s2
-- 9gTU1rI
-- Check if "prog" ends with one of the file extension in
-- "ext_s_5".
--
-- "ext_s_5" are all in lowercase, ensured at 2zdGM8W.
let prog_lc = T.toLower (T.pack prog)
let prog_has_ext = any (`T.isSuffixOf` prog_lc) ext_s_5
-- 6bFwhbv
exe_path_s <- liftM List.concat (
(`mapM` dir_path_s3) (\dir_path -> do
-- 7rO7NIN
-- Synthesize a path
let path = iff (dir_path == T.pack "")
(T.pack prog)
(T.concat [
dir_path
,(T.pack "\\")
,(T.pack prog)
])
-- "exe_path" is used at 4bm0d25.
-- Its value being empty string means file not exist.
exe_path <-
-- 6kZa5cq
-- If "prog" ends with executable file extension
iff prog_has_ext
-- then
(do
file_exists <- (doesFileExist (T.unpack path))
-- 3whKebE
iff file_exists
-- then
-- 2ffmxRF
(return path)
-- else
(return (T.pack ""))
)
-- else
(return (T.pack ""))
-- 2sJhhEV
-- Assume user has omitted the file extension
exe_path_s <- liftM List.concat (
(`mapM` ext_s_5) (\ext -> do
-- 6k9X6GP
-- Synthesize a path with one of the file
-- extensions in PATHEXT
let path_2 = (T.concat [path, ext])
file_exists_2 <-
(doesFileExist (T.unpack path_2))
-- 6kabzQg
iff file_exists_2
-- then
-- 7dui4cD
(return [path_2])
-- else
(return [])
)
)
-- 4bm0d25
iff (exe_path == (T.pack ""))
-- then
(return exe_path_s)
-- then
(return ([exe_path] ++ exe_path_s))
--
)
)
-- 8swW6Av
-- Uniquify
let exe_path_s2 = texts_uniq exe_path_s
-- Convert from Text to String
let exe_path_s3 = map T.unpack exe_path_s2
-- 7y3JlnS
return exe_path_s3
)
-- 4zKrqsC
-- Program entry
main = do
--
arg_s <- getArgs
--
let arg_cnt = length arg_s
-- 9mlJlKg
-- If not exactly one command argument is given
iff (arg_cnt /= 1)
-- then
(do
-- 7rOUXFo
-- Print program usage
let usage = strings_join "\n" [
"Usage: aoikwinwhich PROG",
"",
"#/ PROG can be either name or path",
"aoikwinwhich notepad.exe",
"aoikwinwhich C:\\Windows\\notepad.exe",
"",
"#/ PROG can be either absolute or relative",
"aoikwinwhich C:\\Windows\\notepad.exe",
"aoikwinwhich Windows\\notepad.exe",
"",
"#/ PROG can be either with or without extension",
"aoikwinwhich notepad.exe",
"aoikwinwhich notepad",
"aoikwinwhich C:\\Windows\\notepad.exe",
"aoikwinwhich C:\\Windows\\notepad\n"
]
putStr usage
-- 3nqHnP7
exitWith (ExitFailure 1)
)
-- else
(do
-- 9m5B08H
-- Get executable name or path
let prog = head arg_s
-- 8ulvPXM
-- Find executable paths
exe_path_s <- find_exe_paths prog
-- 5fWrcaF
-- If has found none
iff (length exe_path_s == 0)
-- then
(do
-- 3uswpx0
exitWith (ExitFailure 2)
)
-- else
-- If has found some
(do
-- 9xPCWuS
-- Print to stdout
putStrLn (strings_join "\n" exe_path_s)
-- 4s1yY1b
exitWith (ExitSuccess)
)
)
AoikWinWhich-Hy
;
(import os)
(import os.path)
;
(defn list_uniq [item_s]
;
(setv item_s_uniq [])
(for [item item_s]
(if (not (in item item_s_uniq))
; then
(item_s_uniq.append item)
; else
None
)
)
; Return
item_s_uniq
)
;
(defn find_exe_paths [prog]
; 8f1kRCu
(setv env_pathext (os.environ.get "PATHEXT" None))
; 4fpQ2RB
(if (not env_pathext)
; then
; Return
[]
; else
(do
; 6qhHTHF
; Split into a list of extensions
(setv ext_s (env_pathext.split os.pathsep))
; 2pGJrMW
; Strip
(setv ext_s (list-comp (x.strip) [x ext_s]))
; 2gqeHHl
; Remove empty.
; Must be done after the stripping at 2pGJrMW.
(setv ext_s (list-comp x [x ext_s] (!= x "")))
; 2zdGM8W
; Convert to lowercase
(setv ext_s (list-comp (x.lower) [x ext_s]))
; 2fT8aRB
; Uniquify
(setv ext_s (list_uniq ext_s))
; 4ysaQVN
(setv env_path (os.environ.get "PATH" None))
;
(setv dir_path_s
; 5gGwKZL
(if (not env_path)
; then
; 7bVmOKe
; Go ahead with "dir_path_s" being empty
[]
; else
; 6mPI0lg
; Split into a list of dir paths
(env_path.split os.pathsep)
)
)
; 5rT49zI
; Insert empty dir path to the beginning
;
; Empty dir handles the case that "prog" is a path, either
; relative or absolute. See code 7rO7NIN.
(dir_path_s.insert 0 "")
; 2klTv20
; Uniquify
(setv dir_path_s (list_uniq dir_path_s))
; 9gTU1rI
; Check if "prog" ends with one of the file extension in
; "ext_s".
;
; "ext_s" are all in lowercase, ensured at 2zdGM8W.
(setv prog_lc (prog.lower))
(setv prog_has_ext (prog_lc.endswith (tuple ext_s)))
; "endswith" requires tuple, not list.
; 6bFwhbv
(setv exe_path_s [])
(for [dir_path dir_path_s]
(do
; 7rO7NIN
; Synthesize a path
(setv path
(if (= dir_path "")
; then
prog
; else
(os.path.join dir_path prog)
)
)
; 6kZa5cq
; If "prog" ends with executable file extension
(if prog_has_ext
; then
; 3whKebE
(if (os.path.isfile path)
; then
; 2ffmxRF
(exe_path_s.append path)
; else
None
)
; else
None
)
; 2sJhhEV
; Assume user has omitted the file extension
(for [ext ext_s]
(do
; 6k9X6GP
; Synthesize a path with one of the file extensions
; in PATHEXT
(setv path_2 (+ path ext))
; 6kabzQg
(if (os.path.isfile path_2)
; then
; 7dui4cD
(exe_path_s.append path_2)
; else
None
)
)
)
)
)
; 8swW6Av
; Uniquify
(setv exe_path_s (list_uniq exe_path_s))
; 7y3JlnS
; Return
exe_path_s
)
)
)
; 4zKrqsC
; Program entry
(defmain [&rest args]
; 9mlJlKg
; If not exactly one command argument is given
(if (!= (len args) 2)
; then
(do
; 7rOUXFo
; Print program usage
(print r"Usage: aoikwinwhich PROG
#/ PROG can be either name or path
aoikwinwhich notepad.exe
aoikwinwhich C:\Windows\notepad.exe
#/ PROG can be either absolute or relative
aoikwinwhich C:\Windows\notepad.exe
aoikwinwhich Windows\notepad.exe
#/ PROG can be either with or without extension
aoikwinwhich notepad.exe
aoikwinwhich notepad
aoikwinwhich C:\Windows\notepad.exe
aoikwinwhich C:\Windows\notepad")
; 3nqHnP7
; Exit
;
; Hy 0.11.0 on Windows prints "defmain"'s return value, instead of
; setting the return value as exit code. So we return None here to
; avoid the printing.
None
)
; else
(do
; 9m5B08H
; Get executable name or path
(setv prog (. args[1]))
; 8ulvPXM
; Find executable paths
(setv exe_path_s (find_exe_paths prog))
; 5fWrcaF
; If has found none
(if (not exe_path_s)
; then
; Exit
None
; else
; If has found some
;
(do
; 9xPCWuS
; Print result
(print ((. "\n" join) exe_path_s))
; 4s1yY1b
; Exit
None
)
)
)
)
)
AoikWinWhich-Java
//
package aoikwinwhich;
import static java.lang.System.out;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
public class AoikWinWhich {
public static List<String> find_executable(String prog) {
// 8f1kRCu
String env_var_PATHEXT = System.getenv("PATHEXT");
/// can be null
// 6qhHTHF
// split into a list of extensions
List<String> ext_s = (env_var_PATHEXT == null)
? new LinkedList<>()
: Arrays.asList(env_var_PATHEXT.split(File.pathSeparator));
// 2pGJrMW
// strip
ext_s = ext_s.stream().map(String::trim).collect(Collectors.toList());
// 2gqeHHl
// remove empty
ext_s = ext_s.stream().filter(x -> !x.equals("")).collect(Collectors.toList());
// 2zdGM8W
// convert to lowercase
ext_s = ext_s.stream().map(String::toLowerCase).collect(Collectors.toList());
// 2fT8aRB
// uniquify
ext_s = new LinkedList<>(new LinkedHashSet<>(ext_s));
/// LinkedHashSet keeps the original order.
// 4ysaQVN
String env_var_PATH = System.getenv("PATH");
/// can be null
// 6mPI0lg
List<String> dir_path_s = (env_var_PATH == null)
? new LinkedList<>()
: new LinkedList<>(Arrays.asList(env_var_PATH.split(File.pathSeparator)));
// 5rT49zI
// insert empty dir path to the beginning
//
// Empty dir handles the case that |prog| is a path, either relative or
// absolute. See code 7rO7NIN.
dir_path_s.add(0, "");
// 2klTv20
// uniquify
dir_path_s = new LinkedList<>(new LinkedHashSet<>(dir_path_s));
/// LinkedHashSet keeps the original order.
// 6bFwhbv
List<String> exe_path_s = new LinkedList<>();
for (String dir_path : dir_path_s) {
// 7rO7NIN
// synthesize a path with the dir and prog
final String path = dir_path.equals("") ? prog :
Paths.get(dir_path, prog).toString();
/// |final| is needed for |path| to be used in the lambda below.
// 6kZa5cq
// assume the path has extension, check if it is an executable
if (ext_s.parallelStream().anyMatch(ext -> path.endsWith(ext))) {
if (Files.isRegularFile(Paths.get(path))) {
exe_path_s.add(path);
}
}
// 2sJhhEV
// assume the path has no extension
for (String ext : ext_s) {
// 6k9X6GP
// synthesize a new path with the path and the executable extension
String path_plus_ext = path + ext;
// 6kabzQg
// check if it is an executable
if (Files.isRegularFile(Paths.get(path_plus_ext))) {
exe_path_s.add(path_plus_ext);
}
}
}
//
return exe_path_s;
}
public static void main(String[] args) {
// 9mlJlKg
// check if one cmd arg is given
if (args.length != 1) {
// 7rOUXFo
// print program usage
out.println("Usage: aoikwinwhich PROG");
out.println("");
out.println("#/ PROG can be either name or path");
out.println("aoikwinwhich notepad.exe");
out.println("aoikwinwhich C:\\Windows\\notepad.exe");
out.println("");
out.println("#/ PROG can be either absolute or relative");
out.println("aoikwinwhich C:\\Windows\\notepad.exe");
out.println("aoikwinwhich Windows\\notepad.exe");
out.println("");
out.println("#/ PROG can be either with or without extension");
out.println("aoikwinwhich notepad.exe");
out.println("aoikwinwhich notepad");
out.println("aoikwinwhich C:\\Windows\\notepad.exe");
out.println("aoikwinwhich C:\\Windows\\notepad");
// 3nqHnP7
return;
}
// 9m5B08H
// get name or path of a program from cmd arg
String prog = args[0];
// 8ulvPXM
// find executables
List<String> path_s = find_executable(prog);
// 5fWrcaF
// has found none, exit
if (path_s.size() == 0) {
// 3uswpx0
return;
}
// 9xPCWuS
// has found some, output
String txt = String.join("\n", path_s);
out.println(txt);
//
return;
}
}
AoikWinWhich-JavaScript
//
'use strict';
//
var _fs = require('fs');
var _path = require('path');
var _ = require('underscore');
// add func |endsWith| to String
if (typeof String.prototype.endsWith !== 'function') {
String.prototype.endsWith = function (suffix) {
return this.indexOf(suffix, this.length - suffix.length) !== -1;
};
}
function is_file(path) {
var fstat = null;
try {
fstat = _fs.statSync(path);
} catch (err) {
return false;
}
return fstat && fstat.isFile();
}
function find_executable(prog) {
// 8f1kRCu
var env_var_PATHEXT = process.env.PATHEXT;
/// can be |undefined|
// 6qhHTHF
// split into a list of extensions
var ext_s = !env_var_PATHEXT ? [] : env_var_PATHEXT.split(_path.delimiter);
// 2pGJrMW
// strip
ext_s = _.map(ext_s, function (ext) {
return ext.trim();
});
// 2gqeHHl
// remove empty
ext_s = _.filter(ext_s, function (ext) {
return ext !== '';
});
// 2zdGM8W
// convert to lowercase
ext_s = _.map(ext_s, function (ext) {
return ext.toLowerCase();
});
// 2fT8aRB
// uniquify
ext_s = _.uniq(ext_s);
// 4ysaQVN
var env_var_PATH = process.env.PATH;
/// can be |undefined|
///
/// if has value, there is an ending |;| in it,
/// which results in an ending empty string for the splitting at 3zVznlK
// 6mPI0lg
var dir_path_s = !env_var_PATH ? [] : env_var_PATH.split(_path.delimiter);
/// 3zVznlK
// 5rT49zI
// insert empty dir path to the beginning
//
// Empty dir handles the case that |prog| is a path, either relative or absolute.
// See code 7rO7NIN.
dir_path_s.unshift('');
// 2klTv20
// uniquify
dir_path_s = _.uniq(dir_path_s);
// 6bFwhbv
var exe_path_s = [];
_.each(dir_path_s, function (dir_path) {
// 7rO7NIN
// synthesize a path with the dir and prog
var path = _path.join(dir_path, prog);
// 6kZa5cq
// assume the path has extension, check if it is an executable
if (_.any(ext_s, function (ext) {
return path.endsWith(ext);
})) {
if (is_file(path)) {
exe_path_s.push(path);
}
}
// 2sJhhEV
// assume the path has no extension
_.each(ext_s, function (ext) {
// 6k9X6GP
// synthesize a new path with the path and the executable extension
var path_plus_ext = path + ext;
// 6kabzQg
// check if it is an executable
if (is_file(path_plus_ext)) {
exe_path_s.push(path_plus_ext);
}
});
});
// 8swW6Av
// uniquify
exe_path_s = _.uniq(exe_path_s);
//
return exe_path_s;
}
function print(txt) {
process.stdout.write(txt + '\n');
}
function main() {
// 9mlJlKg
// check if one cmd arg is given
var arg_s = process.argv.slice(2);
if (arg_s.length != 1) {
// 7rOUXFo
// print program usage
print('Usage: aoikwinwhich PROG');
print('');
print('#/ PROG can be either name or path');
print('aoikwinwhich notepad.exe');
print('aoikwinwhich C:\\Windows\\notepad.exe');
print('');
print('#/ PROG can be either absolute or relative');
print('aoikwinwhich C:\\Windows\\notepad.exe');
print('aoikwinwhich Windows\\notepad.exe');
print('');
print('#/ PROG can be either with or without extension');
print('aoikwinwhich notepad.exe');
print('aoikwinwhich notepad');
print('aoikwinwhich C:\\Windows\\notepad.exe');
print('aoikwinwhich C:\\Windows\\notepad');
// 3nqHnP7
return;
}
// 9m5B08H
// get name or path of a program from cmd arg
var prog = arg_s[0];
// 8ulvPXM
// find executables
var path_s = find_executable(prog);
// 5fWrcaF
// has found none, exit
if (!path_s.length) {
// 3uswpx0
return;
}
// 9xPCWuS
// has found some, output
var txt = path_s.join('\n');
print(txt);
// 4s1yY1b
return;
}
//
exports.main = main;
//
if (require.main == module) {
main();
}
AoikWinWhich-Julia
#
function find_exe_paths(prog)
# 8f1kRCu
env_pathext = get(ENV, "PATHEXT", "")
# 4fpQ2RB
if env_pathext == ""
# 9dqlPRg
return []
end
# 6qhHTHF
# Split into a list of extensions
ext_s = split(env_pathext, ";")
# 2pGJrMW
# Strip
ext_s = [strip(ext) for ext=ext_s]
# 2gqeHHl
# Remove empty.
# Must be done after the stripping at 2pGJrMW.
ext_s = filter(x -> x != "", ext_s)
# 2zdGM8W
# Convert to lowercase
ext_s = [lowercase(ext) for ext=ext_s]
# 2fT8aRB
# Uniquify
ext_s = unique(ext_s)
# 4ysaQVN
env_path = get(ENV, "PATH", "")
# 5gGwKZL
if env_path == ""
# 7bVmOKe
# Go ahead with "dir_path_s" being empty
dir_path_s = []
else
# 6mPI0lg
# Split into a list of dir paths
dir_path_s = split(env_path, ";")
end
# 5rT49zI
# Insert empty dir path to the beginning.
#
# Empty dir handles the case that "prog" is a path, either relative or
# absolute. See code 7rO7NIN.
unshift!(dir_path_s, "")
# 2klTv20
# Uniquify
dir_path_s = unique(dir_path_s)
# 9gTU1rI
# Check if "prog" ends with one of the file extension in "ext_s".
#
# "ext_s" are all in lowercase, ensured at 2zdGM8W.
prog_lc = lowercase(prog)
prog_has_ext = (findfirst(ext -> endswith(prog_lc, ext), ext_s)) != 0
# Index value "0" means not found.
# 6bFwhbv
exe_path_s = String[]
for dir_path=dir_path_s
# 7rO7NIN
# Synthesize a path
if dir_path == ""
path = prog
else
path = dir_path * "\\" * prog
end
# 6kZa5cq
# If "prog" ends with executable file extension
if prog_has_ext
# 3whKebE
if isfile(path)
# 2ffmxRF
push!(exe_path_s, path)
end
end
# 2sJhhEV
# Assume user has omitted the file extension
for ext=ext_s
# 6k9X6GP
# Synthesize a path with one of the file extensions in PATHEXT
path_2 = path * ext
# 6kabzQg
if isfile(path_2)
# 7dui4cD
push!(exe_path_s, path_2)
end
end
end
# 8swW6Av
# Uniquify
exe_path_s = unique(exe_path_s)
# 7y3JlnS
return exe_path_s
end
#
function main()
# 9mlJlKg
# If not exactly one command argument is given
if length(ARGS) != 1
usage = """Usage: aoikwinwhich PROG
#/ PROG can be either name or path
aoikwinwhich notepad.exe
aoikwinwhich C:\\Windows\\notepad.exe
#/ PROG can be either absolute or relative
aoikwinwhich C:\\Windows\\notepad.exe
aoikwinwhich Windows\\notepad.exe
#/ PROG can be either with or without extension
aoikwinwhich notepad.exe
aoikwinwhich notepad
aoikwinwhich C:\\Windows\\notepad.exe
aoikwinwhich C:\\Windows\\notepad"""
# 7rOUXFo
# Print program usage
print(usage)
# 3nqHnP7
# Exit
return 1
end
# 9m5B08H
# Get executable name or path
prog = ARGS[1]
# 8ulvPXM
# Find executable paths
exe_path_s = find_exe_paths(prog)
# 5fWrcaF
# If has found none
if length(exe_path_s) == 0
# 3uswpx0
# Exit
return 2
# If has found some
else
# 9xPCWuS
# Print result
print(join(exe_path_s, "\n") * "\n")
# 4s1yY1b
# Exit
return 0
end
end
# 4zKrqsC
# Program entry
exit(main())
AoikWinWhich-Kotlin
//
package aoikwinwhich
import java.io.File
import java.nio.file.Files
import java.nio.file.Paths
import java.util.LinkedHashSet
import java.util.LinkedList
//
object AoikWinWhich {
fun find_executable(prog: String): List<String> {
// 8f1kRCu
val env_var_PATHEXT = System.getenv("PATHEXT")
/// can be null
// 6qhHTHF
// split into a list of extensions
var ext_s =
if (env_var_PATHEXT == null)
listOf<String>()
else
env_var_PATHEXT.split(File.pathSeparator).toList()
// 2pGJrMW
// strip
ext_s = ext_s.map({x -> x.trim()})
// 2gqeHHl
// remove empty
ext_s = ext_s.filter({x -> x != ""})
// 2zdGM8W
// convert to lowercase
ext_s = ext_s.map({x -> x.toLowerCase()})
// 2fT8aRB
// uniquify
ext_s = LinkedHashSet(ext_s).toList()
/// LinkedHashSet keeps the original order.
// 4ysaQVN
val env_var_PATH = System.getenv("PATH")
/// can be null
// 6mPI0lg
var dir_path_s =
if (env_var_PATH == null)
linkedListOf<String>()
else
env_var_PATH.split(File.pathSeparator).toLinkedList()
// 5rT49zI
// insert empty dir path to the beginning
//
// Empty dir handles the case that |prog| is a path, either relative or
// absolute. See code 7rO7NIN.
dir_path_s.add(0, "")
// 2klTv20
// uniquify
dir_path_s = LinkedHashSet(dir_path_s).toLinkedList()
/// LinkedHashSet keeps the original order.
//
val prog_lc = prog.toLowerCase()
val prog_has_ext = ext_s.any({ext -> prog_lc.endsWith(ext)})
// 6bFwhbv
var exe_path_s = linkedListOf<String>()
for (dir_path in dir_path_s) {
// 7rO7NIN
// synthesize a path with the dir and prog
val path =
if (dir_path == "")
prog
else
Paths.get(dir_path, prog).toString()
// 6kZa5cq
// assume the path has extension, check if it is an executable
if (prog_has_ext && Files.isRegularFile(Paths.get(path))) {
exe_path_s.add(path)
}
// 2sJhhEV
// assume the path has no extension
for (ext in ext_s) {
// 6k9X6GP
// synthesize a new path with the path and the executable extension
val path_plus_ext = path + ext
// 6kabzQg
// check if it is an executable
if (Files.isRegularFile(Paths.get(path_plus_ext))) {
exe_path_s.add(path_plus_ext)
}
}
}
// 8swW6Av
// uniquify
exe_path_s = LinkedHashSet(exe_path_s).toLinkedList()
/// LinkedHashSet keeps the original order.
//
return exe_path_s
}
fun main(args: Array<String>) {
// 9mlJlKg
// check if one cmd arg is given
if (args.size != 1) {
// 7rOUXFo
// print program usage
println("""Usage: aoikwinwhich PROG""")
println()
println("""#/ PROG can be either name or path""")
println("""aoikwinwhich notepad.exe""")
println("""aoikwinwhich C:\Windows\notepad.exe""")
println("")
println("""#/ PROG can be either absolute or relative""")
println("""aoikwinwhich C:\Windows\notepad.exe""")
println("""aoikwinwhich Windows\notepad.exe""")
println("")
println("""#/ PROG can be either with or without extension""")
println("""aoikwinwhich notepad.exe""")
println("""aoikwinwhich notepad""")
println("""aoikwinwhich C:\Windows\notepad.exe""")
println("""aoikwinwhich C:\Windows\notepad""")
// 3nqHnP7
return
}
// 9m5B08H
// get name or path of a program from cmd arg
val prog = args[0]
// 8ulvPXM
// find executables
val path_s = find_executable(prog)
// 5fWrcaF
// has found none, exit
if (path_s.size == 0) {
// 3uswpx0
return
}
// 9xPCWuS
// has found some, output
val txt = path_s.join("\n")
println(txt)
// 4s1yY1b
return
}
}
//
fun main(args: Array<String>) {
AoikWinWhich.main(args)
}
AoikWinWhich-Lua
--
-- Copied from |http://lua-users.org/wiki/SplitJoin|.
-- Renamed from |explode| to |string.split|.
-- BEG
function string.split(p,d)
local t, ll
t={}
ll=0
if(#p == 1) then return {p} end
while true do
l=string.find(p,d,ll,true) -- find the next d in the string
if l~=nil then -- if "not not" found then..
table.insert(t, string.sub(p,ll,l-1)) -- Save it in our array.
ll=l+1 -- save just after where we found it for searching next time.
else
table.insert(t, string.sub(p,ll)) -- Save what's left in our array.
break -- Break at end, as it should be, according to the lua manual.
end
end
return t
end
-- END
-- Copied from |http://lua-users.org/wiki/StringTrim|.
-- Renamed from |trim12| to |string.trim|.
-- BEG
function string.trim(s)
local from = s:match"^%s*()"
return from > #s and "" or s:match(".*%S", from)
end
-- END
-- Copied from |http://lua-users.org/wiki/StringRecipes|.
-- Renamed from |string.ends| to |string.endswith|.
-- BEG
function string.endswith(String,End)
return End=='' or string.sub(String,-string.len(End))==End
end
-- END
function map(item_s, func)
local item_s_new = {}
for key, val in ipairs(item_s) do
item_s_new[key] = func(val)
end
return item_s_new
end
function filter(item_s, func)
local item_s_new = {}
local ord = 0
for key, val in ipairs(item_s) do
if func(val) then
ord = ord + 1
item_s_new[ord] = val
end
end
return item_s_new
end
function any(item_s, func)
for key, val in ipairs(item_s) do
if func(val) then
return true
end
end
return false
end
function uniq(item_s)
--
local val_ord_s = {}
local ord_val_s_uniq = {}
--
local ord = 1
for _, val in ipairs(item_s) do
--
val_exists = val_ord_s[val]
--- can be nil
if (not val_exists) then
val_ord_s[val] = ord
ord_val_s_uniq[ord] = val
ord = ord + 1
end
end
table.sort(ord_val_s_uniq, function (va, vb) return val_ord_s[va] < val_ord_s[vb] end)
return ord_val_s_uniq
end
-- Copied from |http://stackoverflow.com/a/4991602|.
-- Choose not to add dependency on |lfs|
-- (http://keplerproject.github.io/luafilesystem/) so use a simple func that
-- only checks if the file is openable, not sure if it is regular file.
-- BEG
function file_exists(name)
local f=io.open(name,"r")
if f~=nil then io.close(f) return true else return false end
end
-- END
function find_executable(prog)
-- 8f1kRCu
local env_var_PATHEXT = os.getenv('PATHEXT')
--- can be null
-- 6qhHTHF
-- split into a list of extensions
local sep = ';'
local ext_s = (not env_var_PATHEXT) and {} or env_var_PATHEXT:split(sep)
-- 2pGJrMW
-- strip
ext_s = map(ext_s, function(x) return x:trim() end)
-- 2gqeHHl
-- remove empty
ext_s = filter(ext_s, function(x) return x ~= '' end)
-- 2zdGM8W
-- convert to lowercase
ext_s = map(ext_s, function(x) return x:lower() end)
-- 2fT8aRB
-- uniquify
ext_s = uniq(ext_s)
-- 4ysaQVN
env_var_PATH = os.getenv('PATH')
--- can be nil
-- 6mPI0lg
local dir_path_s = (not env_var_PATH) and {} or env_var_PATH:split(sep)
-- 5rT49zI
-- insert empty dir path to the beginning
--
-- Empty dir handles the case that |prog| is a path, either relative or
-- absolute. See code 7rO7NIN.
table.insert(dir_path_s, 1, '')
-- 2klTv20
-- uniquify
dir_path_s = uniq(dir_path_s)
--
local prog_has_ext = any(ext_s, function(x) return prog:lower():endswith(x) end)
-- 6bFwhbv
exe_path_s = {}
for _, dir_path in ipairs(dir_path_s) do
-- 7rO7NIN
-- synthesize a path with the dir and prog
path = (dir_path == '') and prog or dir_path .. '\\' .. prog
-- 6kZa5cq
-- assume the path has extension, check if it is an executable
if prog_has_ext and file_exists(path) then
exe_path_s[#exe_path_s+1] = path
end
-- 2sJhhEV
-- assume the path has no extension
for _, ext in ipairs(ext_s) do
-- 6k9X6GP
-- synthesize a new path with the path and the executable extension
path_plus_ext = path .. ext
-- 6kabzQg
-- check if it is an executable
if file_exists(path_plus_ext) then
exe_path_s[#exe_path_s+1] = path_plus_ext
end
end
end
-- 8swW6Av
-- uniquify
exe_path_s = uniq(exe_path_s)
--
return exe_path_s
end
function main()
-- 9mlJlKg
if (#arg ~= 1) then
-- 7rOUXFo
-- print program usage
print([[Usage: aoikwinwhich PROG]])
print('')
print([[#/ PROG can be either name or path]])
print([[aoikwinwhich notepad.exe]])
print([[aoikwinwhich C:\Windows\notepad.exe]])
print('')
print([[#/ PROG can be either absolute or relative]])
print([[aoikwinwhich C:\Windows\notepad.exe]])
print([[aoikwinwhich Windows\notepad.exe]])
print('')
print([[#/ PROG can be either with or without extension]])
print([[aoikwinwhich notepad.exe]])
print([[aoikwinwhich notepad]])
print([[aoikwinwhich C:\Windows\notepad.exe]])
print([[aoikwinwhich C:\Windows\notepad]])
-- 3nqHnP7
return
end
-- 9m5B08H
-- get name or path of a program from cmd arg
local prog = arg[1]
-- 8ulvPXM
-- find executables
local path_s = find_executable(prog)
-- 5fWrcaF
-- has found none, exit
if (#path_s == 0) then
-- 3uswpx0
return
end
-- 9xPCWuS
-- has found some, output
local txt = table.concat(path_s, '\n')
print(txt)
-- 4s1yY1b
return
end
--/
main()
AoikWinWhich-OCaml
(**)
#load "str.cma";;
(**)
let rec list_uniq lst =
match lst with
| [] -> []
| head::tail_s ->
head :: (list_uniq (List.filter (fun x -> x <> head) tail_s))
;;
(**)
let string_endswith str tail =
let str_len = String.length(str) in
let end_len = String.length(tail) in
if str_len < end_len then
false
else (
let str_tail = (String.sub str (str_len - end_len) end_len) in
str_tail = tail
)
;;
(**)
let find_exe_paths (prog) =
(* 8f1kRCu *)
let env_pathext = try Sys.getenv("PATHEXT") with Not_found -> ""
in
(* 4fpQ2RB *)
if env_pathext = "" then (
(* 9dqlPRg *)
(* Return *)
[]
)
else (
(* 6mPI0lg *)
(* Split into a list of extensions *)
let ext_s = (Str.split (Str.regexp ";") env_pathext)
in
(* 2pGJrMW *)
(* Strip *)
let ext_s = List.map (String.trim) ext_s
in
(* 2zdGM8W *)
(* Convert to lowercase *)
let ext_s = List.map (String.lowercase) ext_s
in
(* 2gqeHHl *)
(* Remove empty.
Must be done after the stripping at 2pGJrMW.
*)
let ext_s = List.filter (fun x -> x <> "") ext_s
in
(* 2fT8aRB *)
(* Uniquify*)
let ext_s = list_uniq(ext_s)
in
(* 4ysaQVN *)
let env_path = try Sys.getenv("PATH") with Not_found -> ""
in
(**)
let dir_path_s =
(* 5gGwKZL *)
if env_path = "" then (
(* 7bVmOKe *)
(* Go ahead with "dir_path_s" being empty *)
[]
)
else
(* 6mPI0lg *)
(* Split into a list of dir paths *)
(Str.split (Str.regexp ";") env_path)
in
(* 5rT49zI*)
(* Insert empty dir path to the beginning.
Empty dir handles the case that "prog" is a path, either relative or
absolute. See code 7rO7NIN.
*)
let dir_path_s = ("")::dir_path_s
in
(* 2klTv20 *)
(* Uniquify *)
let dir_path_s = list_uniq dir_path_s
in
(* Check if "prog" ends with one of the file extension in "ext_s"
"ext_s" are all in lowercase, ensured at 2zdGM8W.
*)
let prog_has_ext =
let prog_lc = String.lowercase(prog) in
List.exists
(fun ext -> (string_endswith prog_lc ext)) ext_s in
let exe_path_s = ref [] in
(* 6bFwhbv *)
let call_each item_s func = List.iter func item_s in
begin
call_each dir_path_s (fun dir_path ->
(* 7rO7NIN *)
(* Synthesize a path *)
let path =
if dir_path = "" then
prog
else
String.concat "" [dir_path; "\\"; prog]
in
begin
(* 6kZa5cq *)
(* If "prog" ends with executable file extension *)
if prog_has_ext then
if Sys.file_exists(path) then
(* 2ffmxRF *)
exe_path_s := path :: !exe_path_s
;
(* 2sJhhEV *)
(* Assume user has omitted the file extension *)
call_each ext_s (fun ext ->
(* 6k9X6GP *)
(* Synthesize a path with one of the file extensions in PATHEXT
*)
let path_2 = String.concat "" [path; ext]
in
(* 6kabzQg *)
if Sys.file_exists(path_2) then
(* 7dui4cD *)
exe_path_s := path_2 :: !exe_path_s
);
end
);
(* 8swW6Av *)
(* Uniquify *)
exe_path_s := list_uniq !exe_path_s;
(* Reverse, due to prepending at 2ffmxRF and 7dui4cD *)
exe_path_s := List.rev !exe_path_s;
(* 7y3JlnS *)
(* Return *)
!exe_path_s
end
)
;;
(**)
let main () =
(* 9mlJlKg *)
(* If not exactly one command argument is given *)
if Array.length Sys.argv <> 2 then (
(* 7rOUXFo *)
(* Print program usage *)
let usage = "Usage: aoikwinwhich PROG
#/ PROG can be either name or path
aoikwinwhich notepad.exe
aoikwinwhich C:\\Windows\\notepad.exe
#/ PROG can be either absolute or relative
aoikwinwhich C:\\Windows\\notepad.exe
aoikwinwhich Windows\\notepad.exe
#/ PROG can be either with or without extension
aoikwinwhich notepad.exe
aoikwinwhich notepad
aoikwinwhich C:\\Windows\\notepad.exe
aoikwinwhich C:\\Windows\\notepad"
in
print_endline(usage);
(* 3nqHnP7 *)
(* Exit *)
1
)
else (
(* 9m5B08H *)
(* Get executable name or path *)
let prog = Sys.argv.(1) in
(* 8ulvPXM *)
(* Find executable paths *)
let exe_path_s = find_exe_paths(prog) in
(* 5fWrcaF *)
(* If has found none *)
if List.length(exe_path_s) = 0 then
(* 3uswpx0 *)
(* Exit *)
2
(* 5fWrcaF *)
(* If has found none *)
else (
(* 9xPCWuS *)
(* Print result *)
print_endline(String.concat "\n" exe_path_s);
(* 4s1yY1b *)
(* Exit *)
0
)
);
;;
(* 4zKrqsC *)
(* Program entry *)
let () =
exit(main());
;;
AoikWinWhich-Pascal
//
program AoikWinWhich;
uses
Classes,
SysUtils,
strutils;
function StringSplit(str: string; delim: char): TStringList;
begin
Result := TStringList.Create;
Result.StrictDelimiter := True;
Result.Delimiter := delim;
Result.DelimitedText := str;
end;
function StringListUniq(item_s: TStringList): TStringList;
var
i: integer;
item: string;
begin
Result := TStringList.Create;
for i := 0 to item_s.Count - 1 do
begin
item := item_s[i];
if Result.IndexOf(item) = -1 then
Result.add(item);
end;
end;
function FindExePaths(prog: string): TStringList;
var
env_pathext: string;
i: integer;
ext: string;
ext_s: TStringList;
ext_s_2: TStringList;
env_path: string;
dir_path: string;
dir_path_s: TStringList;
prog_lc: string;
prog_has_ext: boolean;
exe_path_s: TStringList;
path: string;
path2: string;
begin
// 8f1kRCu
env_pathext := GetEnvironmentVariable('PATHEXT');
// 4fpQ2RB
if env_pathext = '' then
// 9dqlPRg
exit();
// 6qhHTHF
// Split into a list of extensions
ext_s := StringSplit(env_pathext, ';');
//
ext_s_2 := TStringList.Create;
for i := 0 to ext_s.Count - 1 do
begin
ext := ext_s[i];
// 2pGJrMW
// Strip
ext := Trim(ext);
// 2gqeHHl
// Remove empty.
// Must be done after the stripping at 2pGJrMW.
if ext <> '' then
begin
// 2zdGM8W
// Convert to lowercase
ext := LowerCase(ext);
ext_s_2.add(ext);
end;
// 2fT8aRB
// Uniquify
ext_s_2 := StringListUniq(ext_s_2);
// 4ysaQVN
env_path := GetEnvironmentVariable('PATH');
// 5gGwKZL
if env_path = '' then
// 7bVmOKe
// Go ahead with "dir_path_s" being empty
dir_path_s := TStringList.Create
else
// 6mPI0lg
// Split into a list of paths
dir_path_s := StringSplit(env_path, ';');
// 5rT49zI
// Insert empty dir path to the beginning.
//
// Empty dir handles the case that "prog" is a path, either relative or
// absolute. See code 7rO7NIN.
dir_path_s.Insert(0, '');
// 2klTv20
// Uniquify
dir_path_s := StringListUniq(dir_path_s);
// 9gTU1rI
// Check if "prog" ends with one of the file extension in "ext_s".
//
// "ext_s_2" are all in lowercase, ensured at 2zdGM8W.
prog_lc := LowerCase(prog);
prog_has_ext := False;
for ext in ext_s_2 do
if AnsiEndsStr(ext, prog_lc) then
begin
prog_has_ext := True;
break;
end;
// 6bFwhbv
exe_path_s := TStringList.Create;
for dir_path in dir_path_s do
begin
// 7rO7NIN
// Synthesize a path
if dir_path = '' then
path := prog
else
path := dir_path + '\' + prog;
// 6kZa5cq
// If "prog" ends with executable file extension
if prog_has_ext then
begin
// 3whKebE
if FileExists(path) then
// 2ffmxRF
exe_path_s.add(path);
end;
// 2sJhhEV
// Assume user has omitted the file extension
for ext in ext_s_2 do
begin
// 6k9X6GP
// Synthesize a path with one of the file extensions in PATHEXT
path2 := path + ext;
// 6kabzQg
if FileExists(path2) then
// 7dui4cD
exe_path_s.add(path2);
end;
end;
end;
// 8swW6Av
// Uniquify
exe_path_s := StringListUniq(exe_path_s);
// 7y3JlnS
Result := exe_path_s;
end;
function Main: integer;
var
usage: string;
prog: string;
exe_path_s: TStringList;
i: integer;
begin
// 9mlJlKg
// If not exactly one command argument is given
if ParamCount <> 1 then
begin
// 7rOUXFo
// Print program usage
usage :=
'Usage: aoikwinwhich PROG'#10 +
#10 +
'#/ PROG can be either name or path'#10 +
'aoikwinwhich notepad.exe'#10 +
'aoikwinwhich C:\Windows\notepad.exe'#10 +
#10 +
'#/ PROG can be either absolute or relative'#10 +
'aoikwinwhich C:\Windows\notepad.exe'#10 +
'aoikwinwhich Windows\notepad.exe'#10 +
#10 +
'#/ PROG can be either with or without extension'#10 +
'aoikwinwhich notepad.exe'#10 +
'aoikwinwhich notepad'#10 +
'aoikwinwhich C:\Windows\notepad.exe'#10 +
'aoikwinwhich C:\Windows\notepad';
Writeln(usage);
// 3nqHnP7
exit(1);
end;
// 9m5B08H
// Get executable name or path
prog := ParamStr(1);
// 8ulvPXM
// Find executable paths
exe_path_s := FindExePaths(prog);
// 5fWrcaF
// If has found none
if exe_path_s.Count = 0 then
begin
// 3uswpx0
exit(2);
end
// If has found some
else
begin
// 9xPCWuS
// Print result
for i := 0 to exe_path_s.Count - 1 do
Writeln(exe_path_s[i]);
// 4s1yY1b
exit(0);
end;
end;
begin
// 4zKrqsC
// Program entry
exitcode := Main;
end.
AoikWinWhich-Perl
#/
use File::Spec;
use List::Util;
#/
sub find_executable {
#/
my $prog = $_[0];
#/ 8f1kRCu
my $env_var_PATHEXT = $ENV{'PATHEXT'};
## can be undef
#/ 6qhHTHF
#/ split into a list of extensions
my @ext_s =
!defined(env_var_PATHEXT)
? ()
: split(';', $env_var_PATHEXT);
#/ 2pGJrMW
#/ strip
s{^\s+|\s+$}{}g for @ext_s;
#/ 2gqeHHl
#/ remove empty
@ext_s = grep {$_ ne ''} @ext_s;
#/ 2zdGM8W
#/ convert to lowercase
$_ = lc for @ext_s;
#/ 2fT8aRB
#/ uniquify
my %seen = ();
my @ext_s = grep {!$seen{$_}++} @ext_s;
#/ 4ysaQVN
my $env_var_PATH = $ENV{'PATH'};
## can be undef
#/ 6mPI0lg
my @dir_path_s =
!defined($env_var_PATH)
? ()
: split(';', $env_var_PATH);
#/ 5rT49zI
#/ insert empty dir path to the beginning
#/
#/ Empty dir handles the case that |prog| is a path, either relative or
#/ absolute. See code 7rO7NIN.
unshift(@dir_path_s, '');
#/ 2klTv20
#/ uniquify
my %seen = ();
my @dir_path_s = grep {!$seen{$_}++} @dir_path_s;
#/ 6bFwhbv
my @exe_path_s = ();
for my $dir_path (@dir_path_s) {
#/ 7rO7NIN
#/ synthesize a path with the dir and prog
my $path = $dir_path eq "" ? $prog :
File::Spec->catpath(undef, $dir_path, $prog);
#/ 6kZa5cq
#/ assume the path has extension, check if it is an executable
if (List::Util::any {2 > 1} @ext_s) {
if (-f $path) {
push(@exe_path_s, $path);
}
}
#/ 2sJhhEV
#/ assume the path has no extension
for my $ext (@ext_s) {
#/ 6k9X6GP
#/ synthesize a new path with the path and the executable extension
my $path_plus_ext = $path . $ext;
#/ 6kabzQg
#/ check if it is an executable
if (-f $path_plus_ext) {
push(@exe_path_s, $path_plus_ext);
}
}
}
#/
return @exe_path_s;
}
sub say {
print @_, "\n";
}
sub main() {
#/ 9mlJlKg
#/ check if one cmd arg is given
my $argv_len = $#ARGV + 1;
if ($argv_len != 1) {
#/ 7rOUXFo
#/ print program usage
say 'Usage: aoikwinwhich PROG';
say '';
say '#/ PROG can be either name or path';
say 'aoikwinwhich notepad.exe';
say 'aoikwinwhich C:\Windows\notepad.exe';
say '';
say '#/ PROG can be either absolute or relative';
say 'aoikwinwhich C:\Windows\notepad.exe';
say 'aoikwinwhich Windows\\notepad.exe';
say '';
say '#/ PROG can be either with or without extension';
say 'aoikwinwhich notepad.exe';
say 'aoikwinwhich notepad';
say 'aoikwinwhich C:\Windows\notepad.exe';
say 'aoikwinwhich C:\Windows\notepad';
#/ 3nqHnP7
return;
}
#/ 9m5B08H
#/ get name or path of a program from cmd arg
my $prog = $ARGV[0];
#/ 8ulvPXM
#/ find executables
my @path_s = find_executable($prog);
#/ 5fWrcaF
#/ has found none, exit
if (scalar @path_s == 0) {
#/ 3uswpx0
return;
}
#/ 9xPCWuS
#/ has found some, output
my $txt = join("\n", @path_s);
say $txt;
#/
return;
}
#/
unless (caller) {
main();
}
AoikWinWhich-PHP
<?php
#/ define a string |endswith| function
function endsWith($str, $sub) {
return (substr($str, strlen($str) - strlen($sub)) == $sub);
}
function find_executable($prog) {
#/ 8f1kRCu
$env_var_PATHEXT = getenv('PATHEXT');
## can be False
#/ 6qhHTHF
#/ split into a list of extensions
$ext_s = ($env_var_PATHEXT === False)
? []
: explode(PATH_SEPARATOR, $env_var_PATHEXT);
#/ 2pGJrMW
#/ strip
$ext_s = array_map(function($x) {
return trim($x);
}, $ext_s);
#/ 2gqeHHl
#/ remove empty
$ext_s = array_filter($ext_s, function($x) {
return $x !== '';
});
#/ 2zdGM8W
#/ convert to lowercase
$ext_s = array_map(function($x) {
return strtolower($x);
}, $ext_s);
#/ 2fT8aRB
#/ uniquify
$ext_s = array_unique($ext_s);
#/ 4ysaQVN
$env_var_PATH = getenv('PATH');
## can be False
#/ 6mPI0lg
$dir_path_s = ($env_var_PATH === False)
? []
: explode(PATH_SEPARATOR, $env_var_PATH);
#/ 5rT49zI
#/ insert empty dir path to the beginning
##
## Empty dir handles the case that |prog| is a path, either relative or
## absolute. See code 7rO7NIN.
array_unshift($dir_path_s, '');
#/ 2klTv20
#/ uniquify
$dir_path_s = array_unique($dir_path_s);
#/ 6bFwhbv
$exe_path_s = Array();
foreach ($dir_path_s as $dir_path) {
#/ 7rO7NIN
#/ synthesize a path with the dir and prog
if ($dir_path === '') {
$path = $prog;
}
else {
$path = implode(DIRECTORY_SEPARATOR, array($dir_path, $prog));
}
#/ 6kZa5cq
## assume the path has extension, check if it is an executable
$path_has_ext = array_filter($ext_s, function($ext) use ($path){
return endsWith($path, $ext);
}) !== array();
if ($path_has_ext && is_file($path)) {
$exe_path_s[] = $path;
}
#/ 2sJhhEV
## assume the path has no extension
foreach ($ext_s as $ext) {
#/ 6k9X6GP
#/ synthesize a new path with the path and the executable extension
$path_plus_ext = $path . $ext;
#/ 6kabzQg
#/ check if it is an executable
if (is_file($path_plus_ext)) {
$exe_path_s[] = $path_plus_ext;
}
}
}
#/
return $exe_path_s;
}
function println($txt) {
print($txt);
print("\n");
}
function main() {
#/ 9mlJlKg
global $argv;
$arg_s = array_slice($argv, 1);
if (count($arg_s) != 1) {
#/ 7rOUXFo
#/ print program usage
println('Usage: aoikwinwhich PROG');
println('');
println('#/ PROG can be either name or path');
println('aoikwinwhich notepad.exe');
println('aoikwinwhich C:\Windows\notepad.exe');
println('');
println('#/ PROG can be either absolute or relative');
println('aoikwinwhich C:\Windows\notepad.exe');
println('aoikwinwhich Windows\notepad.exe');
println('');
println('#/ PROG can be either with or without extension');
println('aoikwinwhich notepad.exe');
println('aoikwinwhich notepad');
println('aoikwinwhich C:\Windows\notepad.exe');
println('aoikwinwhich C:\Windows\notepad');
#/ 3nqHnP7
return;
}
#/ 9m5B08H
#/ get name or path of a program from cmd arg
$prog = $arg_s[0];
#/ 8ulvPXM
#/ find executables
$path_s = find_executable($prog);
#/ 5fWrcaF
#/ has found none, exit
if (empty($path_s)) {
#/ 3uswpx0
return;
}
#/ 9xPCWuS
#/ has found some, output
$txt = implode("\n", $path_s);
println($txt);
#/ 4s1yY1b
return;
}
#/
if (!debug_backtrace())
{
main();
}
?>
AoikWinWhich-Python
# coding: utf-8
#
import os
import sys
#
def list_uniq(item_s):
item_s_uniq = []
for item in item_s:
if item not in item_s_uniq:
item_s_uniq.append(item)
return item_s_uniq
# "exe" means executable, not just paths ending with ".exe"
def find_exe_paths(prog):
# 8f1kRCu
env_pathext = os.environ.get('PATHEXT', None)
# 4fpQ2RB
if not env_pathext:
# 9dqlPRg
return []
# 6qhHTHF
# Split into a list of extensions
ext_s = env_pathext.split(os.pathsep)
# 2pGJrMW
# Strip
ext_s = [x.strip() for x in ext_s]
# 2gqeHHl
# Remove empty.
# Must be done after the stripping at 2pGJrMW.
ext_s = [x for x in ext_s if x != '']
# 2zdGM8W
# Convert to lowercase
ext_s = [x.lower() for x in ext_s]
# 2fT8aRB
# Uniquify
ext_s = list_uniq(ext_s)
# 4ysaQVN
env_path = os.environ.get('PATH', None)
# 5gGwKZL
if not env_path:
# 7bVmOKe
# Go ahead with "dir_path_s" being empty
dir_path_s = []
else:
# 6mPI0lg
# Split into a list of dir paths
dir_path_s = env_path.split(os.pathsep)
# 5rT49zI
# Insert empty dir path to the beginning.
#
# Empty dir handles the case that "prog" is a path, either relative or
# absolute. See code 7rO7NIN.
dir_path_s.insert(0, '')
# 2klTv20
# Uniquify
dir_path_s = list_uniq(dir_path_s)
# 9gTU1rI
# Check if "prog" ends with one of the file extension in "ext_s".
#
# "ext_s" are all in lowercase, ensured at 2zdGM8W.
prog_lc = prog.lower()
prog_has_ext = prog_lc.endswith(tuple(ext_s))
# "endswith" requires tuple, not list.
# 6bFwhbv
exe_path_s = []
for dir_path in dir_path_s:
# 7rO7NIN
# Synthesize a path
if dir_path == '':
path = prog
else:
path = os.path.join(dir_path, prog)
# 6kZa5cq
# If "prog" ends with executable file extension
if prog_has_ext:
# 3whKebE
if os.path.isfile(path):
# 2ffmxRF
exe_path_s.append(path)
# 2sJhhEV
# Assume user has omitted the file extension
for ext in ext_s:
# 6k9X6GP
# Synthesize a path with one of the file extensions in PATHEXT
path_2 = path + ext
# 6kabzQg
if os.path.isfile(path_2):
# 7dui4cD
exe_path_s.append(path_2)
# 8swW6Av
# Uniquify
exe_path_s = list_uniq(exe_path_s)
# 7y3JlnS
return exe_path_s
#
def main():
# 9mlJlKg
# If not exactly one command argument is given
if len(sys.argv) != 2:
# 7rOUXFo
# Print program usage
usage = r"""Usage: aoikwinwhich PROG
#/ PROG can be either name or path
aoikwinwhich notepad.exe
aoikwinwhich C:\Windows\notepad.exe
#/ PROG can be either absolute or relative
aoikwinwhich C:\Windows\notepad.exe
aoikwinwhich Windows\notepad.exe
#/ PROG can be either with or without extension
aoikwinwhich notepad.exe
aoikwinwhich notepad
aoikwinwhich C:\Windows\notepad.exe
aoikwinwhich C:\Windows\notepad"""
print(usage)
# 3nqHnP7
return 1
#
assert len(sys.argv) == 2
# 9m5B08H
# Get executable name or path
prog = sys.argv[1]
# 8ulvPXM
# Find executable paths
exe_path_s = find_exe_paths(prog)
# 5fWrcaF
# If has found none
if not exe_path_s:
# 3uswpx0
return 2
# If has found some
else:
# 9xPCWuS
# Print result
print('\n'.join(exe_path_s))
# 4s1yY1b
return 0
#
assert 0
# 4zKrqsC
# Program entry
if __name__ == '__main__':
sys.exit(main())
AoikWinWhich-Ruby
#/
def find_executable(prog)
#/ 8f1kRCu
env_var_PATHEXT = ENV['PATHEXT']
## can be nil
#/ 6qhHTHF
#/ split into a list of extensions
ext_s = if env_var_PATHEXT.nil?
then []
else env_var_PATHEXT.split(File::PATH_SEPARATOR)
end
#/ 2pGJrMW
#/ strip
ext_s = ext_s.map{|x| x.strip}
#/ 2gqeHHl
#/ remove empty
ext_s = ext_s.select{|x| not x.empty?}
#/ 2zdGM8W
#/ convert to lowercase
ext_s = ext_s.map{|x| x.downcase}
#/ 2fT8aRB
#/ uniquify
ext_s.uniq!
#/ 4ysaQVN
env_var_PATH = ENV['PATH']
## can be nil
#/ 6mPI0lg
dir_path_s = if env_var_PATH.nil?
then []
else env_var_PATH.split(File::PATH_SEPARATOR)
end
#/ 5rT49zI
#/ insert empty dir path to the beginning
##
## Empty dir handles the case that |prog| is a path, either relative or absolute.
## See code 7rO7NIN.
if not dir_path_s.include? ''
dir_path_s.unshift ''
end
#/ 2klTv20
#/ uniquify
dir_path_s.uniq!
#/ 6bFwhbv
exe_path_s = []
dir_path_s.each do |dir_path|
#/ 7rO7NIN
#/ synthesize a path with the dir and prog
if dir_path.empty?
path = prog
else
path = File.join(dir_path, prog)
end
#/ 6kZa5cq
## assume the path has extension, check if it is an executable
if path.end_with?(*ext_s) and File.file? path
exe_path_s.push(path)
end
#/ 2sJhhEV
## assume the path has no extension
ext_s.each do |ext|
#/ 6k9X6GP
#/ synthesize a new path with the path and the executable extension
path_plus_ext = path + ext
#/ 6kabzQg
#/ check if it is an executable
if File.file? path_plus_ext
exe_path_s.push(path_plus_ext)
end
end
end
#/ 8swW6Av
#/ uniquify
exe_path_s.uniq!
#/
exe_path_s.map!{|x| x.sub('/', "\\")}
#/
return exe_path_s
end
def main
#/ 9mlJlKg
if ARGV.length != 1
#/ 7rOUXFo
#/ print program usage
puts('Usage: aoikwinwhich PROG')
puts('')
puts('#/ PROG can be either name or path')
puts('aoikwinwhich notepad.exe')
puts('aoikwinwhich C:\Windows\notepad.exe')
puts('')
puts('#/ PROG can be either absolute or relative')
puts('aoikwinwhich C:\Windows\notepad.exe')
puts('aoikwinwhich Windows\notepad.exe')
puts('')
puts('#/ PROG can be either with or without extension')
puts('aoikwinwhich notepad.exe')
puts('aoikwinwhich notepad')
puts('aoikwinwhich C:\Windows\notepad.exe')
puts('aoikwinwhich C:\Windows\notepad')
return
end
#/ 9m5B08H
#/ get name or path of a program from cmd arg
prog = ARGV[0]
#/ 8ulvPXM
#/ find executables
path_s = find_executable(prog)
#/ 5fWrcaF
#/ has found none, exit
if path_s.empty?
#/ 3uswpx0
return
end
#/ 9xPCWuS
#/ has found some, output
txt = path_s.join("\n")
puts txt
#/ 4s1yY1b
return
end
if __FILE__ == $0
main()
end
AoikWinWhich-Rust
//
use std::ascii::AsciiExt;
use std::env;
use std::fs;
use std::process;
//
fn string_to_str(string: &String) -> &str {
return &string;
}
//
fn string_to_lower(string: &String) -> String {
return string.chars().map(|c| c.to_ascii_lowercase()).collect();
}
//
fn path_is_file(path: &String) -> bool {
return match fs::metadata(path) {
Err(_) => false,
Ok(meta) => meta.is_file(),
};
}
//
fn strings_uniq(item_s: &Vec<String>) -> Vec<String> {
//
let mut item_s_uniq : Vec<String> = Vec::new();
//
for item in item_s.iter() {
if !item_s_uniq.contains(&item) {
item_s_uniq.push(item.to_string());
}
}
//
return item_s_uniq
}
//
fn find_exe_paths(prog: &String) -> Vec<String> {
// 8f1kRCu
let env_pathext = match env::var("PATHEXT") {
Ok(v) => v,
Err(_) => "".to_string(),
};
// 4fpQ2RB
if env_pathext.is_empty() {
// 9dqlPRg
return vec![];
}
// 6qhHTHF
// Split into a list of extensions
let mut ext_s : Vec<String> = env_pathext.split(";").map(|x| x.to_string())
.collect();
// 2pGJrMW
// Strip
ext_s = ext_s.iter().map(|x| x.trim().to_string()).collect();
// 2gqeHHl
// Remove empty.
// Must be done after the stripping at 2pGJrMW.
ext_s = ext_s.iter().filter(|x| !x.is_empty()).map(|x| x.to_string())
.collect();
// 2zdGM8W
// Convert to lowercase
ext_s = ext_s.iter().map(|x| string_to_lower(x)).collect();
// 2fT8aRB
// Uniquify
ext_s = strings_uniq(&ext_s);
// 4ysaQVN
let env_path = match env::var("PATH") {
Ok(v) => v,
Err(_) => "".to_string(),
};
// 5gGwKZL
let mut dir_path_s : Vec<String> =
// 7bVmOKe
// Go ahead with "dir_path_s" being empty
if env_path.is_empty() {
vec![]
}
else {
// 6mPI0lg
// Split into a list of dir paths
env_path.split(";").map(|x| x.to_string()).collect()
};
// 5rT49zI
// Insert empty dir path to the beginning.
//
// Empty dir handles the case that "prog" is a path, either relative or
// absolute. See code 7rO7NIN.
dir_path_s.insert(0, "".to_string());
// 2klTv20
// Uniquify
dir_path_s = strings_uniq(&dir_path_s);
// 9gTU1rI
// Check if "prog" ends with one of the file extension in "ext_s".
//
// "ext_s" are all in lowercase, ensured at 2zdGM8W.
let prog_lc : &str = & string_to_lower(prog);
let prog_has_ext = ext_s.iter().find(|ext|
prog_lc.ends_with(string_to_str(ext))).is_some();
// 6bFwhbv
let mut exe_path_s : Vec<String> = Vec::new();
for dir_path in dir_path_s.iter() {
// 7rO7NIN
// Synthesize a path
let path =
if dir_path.is_empty() {
prog.to_owned()
}
else {
format!("{}\\{}", dir_path, prog)
};
// 6kZa5cq
// If "prog" ends with executable file extension
if prog_has_ext {
// 3whKebE
if path_is_file(&path) {
// 2ffmxRF
exe_path_s.push(path.to_owned());
}
}
// 2sJhhEV
// Assume user has omitted the file extension
for ext in ext_s.iter() {
// 6k9X6GP
// Synthesize a path with one of the file extensions in PATHEXT
let path_2 = format!("{}{}", path, ext);
// 6kabzQg
if path_is_file(&path_2) {
// 7dui4cD
exe_path_s.push(path_2);
}
}
}
// 8swW6Av
// Uniquify
exe_path_s = strings_uniq(&exe_path_s);
// 7y3JlnS
return exe_path_s;
}
// 4zKrqsC
// Program entry
fn main() {
//
let arg_s: Vec<_> = env::args().collect();
// 9mlJlKg
// If not exactly one command argument is given
if arg_s.len() != 2 {
// 7rOUXFo
// Print program usage
let usage = "Usage: aoikwinwhich PROG
#/ PROG can be either name or path
aoikwinwhich notepad.exe
aoikwinwhich C:\\Windows\\notepad.exe
#/ PROG can be either absolute or relative
aoikwinwhich C:\\Windows\\notepad.exe
aoikwinwhich Windows\\notepad.exe
#/ PROG can be either with or without extension
aoikwinwhich notepad.exe
aoikwinwhich notepad
aoikwinwhich C:\\Windows\\notepad.exe
aoikwinwhich C:\\Windows\\notepad";
println!("{}", usage);
// 3nqHnP7
process::exit(1);
}
// 9m5B08H
// Get executable name or path
let ref prog = arg_s[1];
// 8ulvPXM
// Find executable paths
let ref exe_path_s = find_exe_paths(prog);
// 5fWrcaF
// If has found none
if arg_s.len() == 0 {
// 3uswpx0
process::exit(2);
}
else {
// 9xPCWuS
// Print result
println!("{}", exe_path_s.connect("\n"));
// 4s1yY1b
process::exit(0);
}
}
AoikWinWhich-Scala
//
package aoikwinwhich
import java.io.File
import java.nio.file.Files
import java.nio.file.Paths
import scala.collection.mutable.ListBuffer
//
object AoikWinWhich {
def find_executable(prog: String): List[String] = {
// 8f1kRCu
val env_var_PATHEXT = System.getenv("PATHEXT")
/// can be null
// 6qhHTHF
// split into a list of extensions
var ext_s =
if (env_var_PATHEXT == null)
List[String]()
else
env_var_PATHEXT.split(File.pathSeparator).toList
// 2pGJrMW
// strip
ext_s = ext_s.map(_.trim)
// 2gqeHHl
// remove empty
ext_s = ext_s.filter(_ != "")
// 2zdGM8W
// convert to lowercase
ext_s = ext_s.map(_.toLowerCase)
// 2fT8aRB
// uniquify
ext_s = ext_s.distinct
/// |distinct| keeps the original order.
// 4ysaQVN
val env_var_PATH = System.getenv("PATH")
/// can be null
// 6mPI0lg
var dir_path_s =
if (env_var_PATH == null)
ListBuffer[String]()
else
env_var_PATH.split(File.pathSeparator).to[ListBuffer]
// 5rT49zI
// insert empty dir path to the beginning
//
// Empty dir handles the case that |prog| is a path, either relative or
// absolute. See code 7rO7NIN.
"" +=: dir_path_s
// 2klTv20
// uniquify
dir_path_s = dir_path_s.distinct
/// |distinct| keeps the original order.
// 6bFwhbv
val exe_path_s = ListBuffer[String]()
for (dir_path <- dir_path_s) {
// 7rO7NIN
// synthesize a path with the dir and prog
val path =
if (dir_path == "")
prog
else
Paths.get(dir_path, prog).toString
// 6kZa5cq
// assume the path has extension, check if it is an executable
if (ext_s.exists(path.endsWith _)) {
if (Files.isRegularFile(Paths.get(path))) {
exe_path_s += path
}
}
// 2sJhhEV
// assume the path has no extension
for (ext <- ext_s) {
// 6k9X6GP
// synthesize a new path with the path and the executable extension
val path_plus_ext = path + ext
// 6kabzQg
// check if it is an executable
if (Files.isRegularFile(Paths.get(path_plus_ext))) {
exe_path_s += path_plus_ext
}
}
}
//
return exe_path_s.toList
}
def main(args: Array[String]) {
// 9mlJlKg
// check if one cmd arg is given
if (args.length != 1) {
// 7rOUXFo
// print program usage
println("Usage: aoikwinwhich PROG")
println("")
println("#/ PROG can be either name or path")
println("aoikwinwhich notepad.exe")
println("aoikwinwhich C:\\Windows\\notepad.exe")
println("")
println("#/ PROG can be either absolute or relative")
println("aoikwinwhich C:\\Windows\\notepad.exe")
println("aoikwinwhich Windows\\notepad.exe")
println("")
println("#/ PROG can be either with or without extension")
println("aoikwinwhich notepad.exe")
println("aoikwinwhich notepad")
println("aoikwinwhich C:\\Windows\\notepad.exe")
println("aoikwinwhich C:\\Windows\\notepad")
// 3nqHnP7
return
}
// 9m5B08H
// get name or path of a program from cmd arg
val prog = args(0)
// 8ulvPXM
// find executables
val path_s = find_executable(prog)
// 5fWrcaF
// has found none, exit
if (path_s.size == 0) {
// 3uswpx0
return
}
// 9xPCWuS
// has found some, output
val txt = path_s.mkString("\n")
println(txt)
//
return
}
}
AoikWinWhich-Scheme
;
#lang scheme
;
(define (string-endswith str end)
(let ([str_len ; be
(string-length str)
]
[end_len ; be
(string-length end)
])
; then
(if (< str_len end_len)
; then
#f
; else
(equal? end (substring str (- str_len end_len)))
)
)
)
;
(define (find_exe_paths prog)
; 8f1kRCu
(let ([env_pathext (getenv "PATHEXT")])
; in
; 4fpQ2RB
(if (not env_pathext)
; then
; 9dqlPRg
; Return
'()
; else
; 6qhHTHF
; Split into a list of extensions
(let ([ext_s
; be
(string-split env_pathext ";")
])
; in
; 2pGJrMW
; Strip
(let ([ext_s
; be
(for/list ([ext ext_s]) (string-trim ext))
])
; in
; 2gqeHHl
; Remove empty.
; Must be done after the stripping at 2pGJrMW.
(let ([ext_s
; be
(filter (lambda (x) (not (equal? x ""))) ext_s)
])
; in
; 2zdGM8W
; Convert to lowercase
(let ([ext_s
; be
(for/list ([ext ext_s]) (string-downcase ext))
])
; in
; 2fT8aRB
; Uniquify
(let ([ext_s
; be
(remove-duplicates ext_s)
])
; in
; 4ysaQVN
(let ([env_path
; be
(getenv "PATH")])
; in
;
(let ([dir_path_s
; be
; 5gGwKZL
(if (not env_path)
; then
'()
; else
; 6mPI0lg
; Split into a list of extensions
(string-split env_path ";")
)
])
; in
; 5rT49zI
; Insert empty dir path to the beginning.
;
; Empty dir handles the case that "prog" is a path,
; either relative or absolute. See code 7rO7NIN.
(let ([dir_path_s
; be
(cons "" dir_path_s)
])
; in
; 2klTv20
; Uniquify
(let ([dir_path_s
; be
(remove-duplicates dir_path_s)
])
; in
; 9gTU1rI
; Check if "prog" ends with one of the file
; extension in "ext_s".
;
; "ext_s" are all in lowercase, ensured at 2zdGM8W.
(let ([prog_lc
; be
(string-downcase prog)
])
; in
(let ([prog_has_ext
; be
(findf (lambda (ext) (string-endswith prog_lc ext))
ext_s)
])
; in
; 6bFwhbv
(let ([exe_path_s
; be
'()
])
; in
(begin
(for ([dir_path dir_path_s])
; 7rO7NIN
; Synthesize a path
(let ([path ; be
(if (equal? dir_path "")
; then
prog
;else
(string-join
(list dir_path "\\" prog) ""
)
)
])
; in
(begin
; 6kZa5cq
; If "prog" ends with executable file
; extension
(if prog_has_ext
; then
; 3whKebE
(if (file-exists? path)
; then
; 2ffmxRF
; Use "cons" so remember to
; reverse at 2qScrZs
(set! exe_path_s
(cons path exe_path_s)
)
; else
#f
)
; else
#f
)
; 2sJhhEV
; Assume user has omitted the file
; extension
(for ([ext ext_s])
; 6k9X6GP
; Synthesize a path with one of the
; file extensions in PATHEXT
(let ([path
; be
(string-append path ext)
])
; in
; 6kabzQg
(if (file-exists? path)
; then
; 7dui4cD
(set! exe_path_s (cons path exe_path_s))
; Use "cons" so remember to
; reverse at 2qScrZs
; else
#f
)
)
)
)
)
)
; Reverse due to "cons" at 2ffmxRF and
; 7dui4cD
(let ([exe_path_s
; be
(reverse exe_path_s)
])
; in
; 8swW6Av
; Uniquify
(let ([exe_path_s
; be
(remove-duplicates exe_path_s)
])
; in
; 2qScrZs
; Return
exe_path_s
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
)
;
(define (main)
;
(let ([cmd_len ; be
(vector-length (current-command-line-arguments))
])
; 9mlJlKg
; If not exactly one command argument is given
(if (not (equal? cmd_len 1))
; then
(begin
; 7rOUXFo
; Print program usage
(printf "Usage: aoikwinwhich PROG
#/ PROG can be either name or path
aoikwinwhich notepad.exe
aoikwinwhich C:\\Windows\\notepad.exe
#/ PROG can be either absolute or relative
aoikwinwhich C:\\Windows\\notepad.exe
aoikwinwhich Windows\\notepad.exe
#/ PROG can be either with or without extension
aoikwinwhich notepad.exe
aoikwinwhich notepad
aoikwinwhich C:\\Windows\\notepad.exe
aoikwinwhich C:\\Windows\\notepad
")
; 3nqHnP7
; Exit
1
)
; else
; 9m5B08H
; Get executable name or path
(let ([prog ; be
(vector-ref (current-command-line-arguments) 0)
])
; then
; 8ulvPXM
; Find executable paths
(let ([exe_path_s ; be
(find_exe_paths prog)
])
; 5fWrcaF
; Has found none
(if (empty? exe_path_s)
; then
; 3uswpx0
; Exit
2
; else
(begin
; 9xPCWuS
; Print result
(printf (string-append (string-join exe_path_s "\n") "\n"))
; 4s1yY1b
; Exit
0
)
)
)
)
)
)
)
; 4zKrqsC
; Program entry
(exit (main))
AoikWinWhich-Tcl
#/
proc ret {x} {
return $x
}
#/ Modified from |http://stackoverflow.com/a/3235303|
##
## This proc returns a func-like list with |apply| being first item, and
## |apply|'s first arg (i.e. func definition) as second item.
## When the result list is expanded using syntax |{*}$f|, |apply| becomes the
## command, it will perform the func call. Any following args become args of
## the func call.
##
## Syntax for creating a func-like list:
## '''
## set fl [func {x} {expr $x > 0}]
## '''
##
## Syntax for calling a func-like list:
## '''
## {*}$fl $arg
## '''
proc func {args body} {
set ns [uplevel 1 namespace current]
return [list ::apply [list $args $body $ns]]
}
proc any {item_s funcl} {
foreach item $item_s {
if {[{*}$funcl $item] != 0} {
return 1
}
}
return 0
}
#/ Modified from |http://stackoverflow.com/a/20376860|
proc uniq item_s {
set item_d [dict create]
foreach item $item_s {
dict set item_d $item 1
}
return [dict keys $item_d]
}
proc endswith {hay ndl} {
set hay_len [string length $hay]
set ndl_len [string length $ndl]
if {[expr $hay_len < $ndl_len]} {
return 0
} else {
if {[expr [string last $ndl $hay] == [expr $hay_len - $ndl_len]]} {
return 1
} else {
return 0
}
}
}
proc find_executable prog {
#/ 8f1kRCu
set env_var_PATHEXT [
if {[info exists ::env(PATHEXT)]} {
ret $::env(PATHEXT)
} else {
ret {}
}
]
#/ 6qhHTHF
#/ split into a list of extensions
set ext_s [
if {[string length $env_var_PATHEXT] == 0} {
ret [list]
} else {
ret [split $env_var_PATHEXT ";"]
}
]
#/ 2pGJrMW
#/ strip
set ext_s [lmap x $ext_s {set x [string trim $x]}]
#/ 2gqeHHl
#/ remove empty
set ext_s [lmap x $ext_s {
if {[string length $x] == 0} continue
set x
}
]
#/ 2zdGM8W
#/ convert to lowercase
set ext_s [lmap x $ext_s {set x [string tolower $x]}]
#/ 2fT8aRB
#/ uniquify
set ext_s [uniq $ext_s]
#/ 4ysaQVN
set env_var_PATH [
if {[info exists ::env(PATH)]} {
ret $::env(PATH)
} else {
ret {}
}
]
#/ 6mPI0lg
set dir_path_s [
if {[string length $env_var_PATH] == 0} {
ret [list]
} else {
ret [split $env_var_PATH ";"]
}
]
#/ 5rT49zI
#/ insert empty dir path to the beginning
##
## Empty dir handles the case that |prog| is a path, either relative or
## absolute. See code 7rO7NIN.
set dir_path_s [linsert $dir_path_s 0 ""]
#/ 2klTv20
#/ uniquify
set dir_path_s [uniq $dir_path_s]
#/
set prog_lc [string tolower $prog]
set func_body "endswith $prog_lc \$ext"
## Must substitute |$prog_lc| to its value here
## because |func| below does not support closure.
set prog_has_ext [any $ext_s [func {ext} $func_body]]
#/ 6bFwhbv
set exe_path_s [list]
foreach dir_path $dir_path_s {
#/ 7rO7NIN
#/ synthesize a path with the dir and prog
set path [
if {$dir_path == ""} {
ret $prog
} else {
ret [string cat $dir_path [file separator] $prog]
}
]
#/ 6kZa5cq
## assume the path has extension, check if it is an executable
if {$prog_has_ext && [file isfile $path]} {
set exe_path_s [lappend exe_path_s $path]
}
#/ 2sJhhEV
## assume the path has no extension
foreach ext $ext_s {
#/ 6k9X6GP
#/ synthesize a new path with the path and the executable extension
set path_plus_ext [string cat $path $ext]
#/ 6kabzQg
#/ check if it is an executable
if {[file isfile $path_plus_ext]} {
set exe_path_s [lappend exe_path_s $path_plus_ext]
}
}
}
#/ 8swW6Av
#/ uniquify
set exe_path_s [uniq $exe_path_s]
#/
return $exe_path_s
}
proc main {} {
#/ 9mlJlKg
if {[llength $::argv] != 1} {
#/ 7rOUXFo
#/ print program usage
puts {Usage: aoikwinwhich PROG}
puts {}
puts {#/ PROG can be either name or path}
puts {aoikwinwhich notepad.exe}
puts {aoikwinwhich C:\Windows\notepad.exe}
puts {}
puts {#/ PROG can be either absolute or relative}
puts {aoikwinwhich C:\Windows\notepad.exe}
puts {aoikwinwhich Windows\notepad.exe}
puts {}
puts {#/ PROG can be either with or without extension}
puts {aoikwinwhich notepad.exe}
puts {aoikwinwhich notepad}
puts {aoikwinwhich C:\Windows\notepad.exe}
puts {aoikwinwhich C:\Windows\notepad}
#/ 3nqHnP7
return
}
#/ 9m5B08H
#/ get name or path of a program from cmd arg
set prog [lindex $::argv 0]
#/ 8ulvPXM
#/ find executables
set path_s [find_executable $prog]
#/ 5fWrcaF
#/ has found none, exit
if {[llength $path_s] == 0} {
#/ 3uswpx0
return
}
#/ 9xPCWuS
#/ has found some, output
set txt [join $path_s "\n"]
puts $txt
#/ 4s1yY1b
return
}
main
AoikWinWhich-VB.NET
''
Imports System.IO
''
Module AoikWinWhich
Function find_executable(ByVal prog As String) As List(Of String)
'' 8f1kRCu
Dim env_var_PATHEXT = Environment.GetEnvironmentVariable("PATHEXT")
''# can be Nothing
'' 6qhHTHF
'' split into a list of extensions
Dim ext_s = If(env_var_PATHEXT = Nothing,
New List(Of String)(),
New List(Of String)(env_var_PATHEXT.Split(Path.PathSeparator))
)
'' 2pGJrMW
'' strip
ext_s = ext_s.Select(Function(x) x.Trim()).ToList()
'' 2gqeHHl
'' remove empty
ext_s = ext_s.Where(Function(x) x <> "").ToList()
'' 2zdGM8W
'' convert to lowercase
ext_s = ext_s.Select(Function(x) x.ToLower()).ToList()
'' 2fT8aRB
'' uniquify
ext_s = ext_s.Distinct().ToList()
'' 4ysaQVN
Dim env_var_PATH = Environment.GetEnvironmentVariable("PATH")
''# can be Nothing
Dim dir_path_s = If(env_var_PATH = Nothing,
New List(Of String)(),
New List(Of String)(env_var_PATH.Split(Path.PathSeparator))
)
'' 5rT49zI
'' insert empty dir path to the beginning
''
'' Empty dir handles the case that |prog| is a path, either relative or
'' absolute. See code 7rO7NIN.
dir_path_s.Insert(0, "")
'' 2klTv20
'' uniquify
dir_path_s = dir_path_s.Distinct().ToList()
''
Dim prog_lc = prog.ToLower()
Dim prog_has_ext = ext_s.Any(Function(ext) prog_lc.EndsWith(ext))
'' 6bFwhbv
Dim exe_path_s = New List(Of String)
For Each dir_path In dir_path_s
'' 7rO7NIN
'' synthesize a path with the dir and prog
Dim file_path = If(dir_path = "",
prog,
Path.Combine(dir_path, prog)
)
'' 6kZa5cq
'' assume the path has extension, check if it is an executable
If prog_has_ext And File.Exists(file_path) Then
exe_path_s.Add(file_path)
End If
'' 2sJhhEV
'' assume the path has no extension
For Each ext In ext_s
'' 6k9X6GP
'' synthesize a new path with the path and the executable extension
Dim path_plus_ext = file_path + ext
'' 6kabzQg
'' check if it is an executable
If File.Exists(path_plus_ext) Then
exe_path_s.Add(path_plus_ext)
End If
Next
Next
'' 8swW6Av
'' uniquify
exe_path_s = exe_path_s.Distinct().ToList()
''
Return exe_path_s
End Function
Sub Main()
'' 9mlJlKg
Dim args = Environment.GetCommandLineArgs()
''# first arg is this program's path.
If args.Length <> 2 Then
'' 7rOUXFo
'' print program usage
Console.WriteLine("Usage: aoikwinwhich PROG")
Console.WriteLine("")
Console.WriteLine("#/ PROG can be either name or path")
Console.WriteLine("aoikwinwhich notepad.exe")
Console.WriteLine("aoikwinwhich C:\Windows\notepad.exe")
Console.WriteLine("")
Console.WriteLine("#/ PROG can be either absolute or relative")
Console.WriteLine("aoikwinwhich C:\Windows\notepad.exe")
Console.WriteLine("aoikwinwhich Windows\notepad.exe")
Console.WriteLine("")
Console.WriteLine("#/ PROG can be either with or without extension")
Console.WriteLine("aoikwinwhich notepad.exe")
Console.WriteLine("aoikwinwhich notepad")
Console.WriteLine("aoikwinwhich C:\Windows\notepad.exe")
Console.WriteLine("aoikwinwhich C:\Windows\notepad")
'' 3nqHnP7
Return
End If
'' 9m5B08H
'' get name or path of a program from cmd arg
Dim prog = args(1)
'' 8ulvPXM
'' find executables
Dim path_s = find_executable(prog)
'' 5fWrcaF
'' has found none, exit
If path_s.Count = 0 Then
'' 3uswpx0
Return
End If
'' 9xPCWuS
'' has found some, output
Dim txt = String.Join(Environment.NewLine, path_s)
Console.WriteLine(txt)
'' 4s1yY1b
Return
End Sub
End Module
AoikWinWhich-Xtend
//
package aoikwinwhich
import java.io.File
import java.nio.file.Files
import java.nio.file.Paths
import java.util.Arrays
import java.util.LinkedHashSet
import java.util.LinkedList
import java.util.List
//
class AoikWinWhich {
def static List<String> find_executable(String prog) {
// 8f1kRCu
val env_var_PATHEXT = System.getenv("PATHEXT")
/// can be null
// 6qhHTHF
// split into a list of extensions
var ext_s =
if (env_var_PATHEXT == null)
newLinkedList
else
Arrays.asList(env_var_PATHEXT.split(File.pathSeparator))
// 2pGJrMW
// strip
ext_s = ext_s.map[ x | x.trim() ].toList()
// 2gqeHHl
// remove empty
ext_s = ext_s.filter[ x | x != "" ].toList()
// 2zdGM8W
// convert to lowercase
ext_s = ext_s.map[ x | x.toLowerCase() ].toList()
// 2fT8aRB
// uniquify
ext_s = new LinkedList(new LinkedHashSet(ext_s))
/// LinkedHashSet keeps the original order.
// 4ysaQVN
val env_var_PATH = System.getenv("PATH")
/// can be null
// 6mPI0lg
var dir_path_s =
if (env_var_PATH == null)
newLinkedList
else
new LinkedList(Arrays.asList(env_var_PATH.split(File.pathSeparator)))
// 5rT49zI
// insert empty dir path to the beginning
//
// Empty dir handles the case that |prog| is a path, either relative or
// absolute. See code 7rO7NIN.
dir_path_s.add(0, "")
// 2klTv20
// uniquify
dir_path_s = new LinkedList(new LinkedHashSet(dir_path_s))
/// LinkedHashSet keeps the original order.
//
val prog_lc = prog.toLowerCase()
val prog_has_ext = ext_s.exists[ ext | prog_lc.endsWith(ext) ]
// 6bFwhbv
var exe_path_s = new LinkedList<String>()
for (String dir_path : dir_path_s) {
// 7rO7NIN
// synthesize a path with the dir and prog
val path =
if (dir_path == "")
prog
else
Paths.get(dir_path, prog).toString()
// 6kZa5cq
// assume the path has extension, check if it is an executable
if (prog_has_ext && Files.isRegularFile(Paths.get(path))) {
exe_path_s.add(path)
}
// 2sJhhEV
// assume the path has no extension
for (String ext : ext_s) {
// 6k9X6GP
// synthesize a new path with the path and the executable extension
val path_plus_ext = path + ext
// 6kabzQg
// check if it is an executable
if (Files.isRegularFile(Paths.get(path_plus_ext))) {
exe_path_s.add(path_plus_ext)
}
}
}
// 8swW6Av
// uniquify
exe_path_s = new LinkedList(new LinkedHashSet(exe_path_s))
/// LinkedHashSet keeps the original order.
//
return exe_path_s
}
def static void main(String[] args) {
// 9mlJlKg
// check if one cmd arg is given
if (args.length != 1) {
// 7rOUXFo
// print program usage
println('Usage: aoikwinwhich PROG')
println('')
println('#/ PROG can be either name or path')
println('aoikwinwhich notepad.exe')
println('aoikwinwhich C:\\Windows\\notepad.exe')
println('')
println('#/ PROG can be either absolute or relative')
println('aoikwinwhich C:\\Windows\\notepad.exe')
println('aoikwinwhich Windows\\notepad.exe')
println('')
println('#/ PROG can be either with or without extension')
println('aoikwinwhich notepad.exe')
println('aoikwinwhich notepad')
println('aoikwinwhich C:\\Windows\\notepad.exe')
println('aoikwinwhich C:\\Windows\\notepad')
// 3nqHnP7
return
}
// 9m5B08H
// get name or path of a program from cmd arg
val prog = args.get(0)
// 8ulvPXM
// find executables
val path_s = find_executable(prog)
// 5fWrcaF
// has found none, exit
if (path_s.size() == 0) {
// 3uswpx0
return
}
// 9xPCWuS
// has found some, output
val txt = String.join("\n", path_s)
println(txt)
// 4s1yY1b
return
}
}
Comments: