mirror of
https://github.com/RubyMetric/chsrc
synced 2025-10-09 21:33:23 +08:00
Move to include
This commit is contained in:
373
include/chsrc.h
Normal file
373
include/chsrc.h
Normal file
@@ -0,0 +1,373 @@
|
||||
/** ------------------------------------------------------------
|
||||
* File : chsrc.h
|
||||
* License : GPLv3
|
||||
* Authors : Aoran Zeng <ccmywish@qq.com>
|
||||
* Created on : <2023-08-29>
|
||||
* Last modified : <2023-10-05>
|
||||
*
|
||||
* chsrc:
|
||||
*
|
||||
* chsrc.c 头文件
|
||||
* ------------------------------------------------------------*/
|
||||
|
||||
#include "xy.h"
|
||||
#include "sources.h"
|
||||
|
||||
|
||||
#define App_Prefix "chsrc: "
|
||||
#define chsrc_success(str) xy_success(xy_2strjoin(App_Prefix, (str)))
|
||||
#define chsrc_info(str) xy_info(xy_2strjoin(App_Prefix, (str)))
|
||||
#define chsrc_warn(str) xy_warn(xy_2strjoin(App_Prefix, (str)))
|
||||
#define chsrc_error(str) xy_error(xy_2strjoin(App_Prefix, (str)))
|
||||
|
||||
|
||||
/**
|
||||
* 检测二进制程序是否存在
|
||||
*
|
||||
* @param check_cmd 检测 `progname` 是否存在的一段命令,一般来说,填 `progname` 本身即可,
|
||||
* 但是某些情况下,需要使用其他命令绕过一些特殊情况,比如 python 这个命令在Windows上
|
||||
* 会自动打开 Microsoft Store,需避免
|
||||
*
|
||||
* @param progname 要检测的二进制程序名
|
||||
*/
|
||||
bool
|
||||
query_program_exist (char* check_cmd, char* progname)
|
||||
{
|
||||
char* which = check_cmd;
|
||||
|
||||
int ret = system(which);
|
||||
|
||||
// char buf[32] = {0}; sprintf(buf, "错误码: %d", ret);
|
||||
|
||||
if (0!=ret) {
|
||||
// xy_warn (xy_strjoin(4, "× 命令 ", progname, " 不存在,", buf));
|
||||
xy_warn (xy_strjoin(3, "× 命令 ", progname, " 不存在"));
|
||||
return false;
|
||||
} else {
|
||||
xy_success (xy_strjoin(3, "√ 命令 ", progname, " 存在"));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 用于 _setsrc 函数,检测用户输入的镜像站code,是否存在于该target可用源中
|
||||
*
|
||||
* @param target 目标名
|
||||
* @param input 如果用户输入 default 或者 def,则选择第一个源
|
||||
*/
|
||||
#define find_mirror(s, input) query_mirror_exist(s##_sources, s##_sources_n, (char*)#s+3, input)
|
||||
int
|
||||
query_mirror_exist (SourceInfo* sources, size_t size, char* target, char* input)
|
||||
{
|
||||
if (0==size) {
|
||||
xy_error(xy_strjoin(3, "chsrc: 当前 ", target, " 无任何可用源,请联系维护者"));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (1==size) {
|
||||
xy_success(xy_strjoin(5, "chsrc: ", sources[0].mirror->name, " 是 ", target, " 目前唯一可用镜像站,感谢他们的慷慨支持"));
|
||||
}
|
||||
|
||||
if (xy_streql("default", input) || xy_streql("def", input)) {
|
||||
xy_info ("chsrc: 默认使用维护团队测速第一的源");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int idx = 0;
|
||||
SourceInfo source = sources[0];
|
||||
|
||||
bool exist = false;
|
||||
for (int i=0; i<size; i++)
|
||||
{
|
||||
source = sources[i];
|
||||
if (xy_streql(source.mirror->code, input)) {
|
||||
idx = i;
|
||||
exist = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!exist) {
|
||||
xy_error (xy_strjoin(3, "chsrc: 镜像站 ", input, " 不存在"));
|
||||
xy_error (xy_2strjoin("chsrc: 查看可使用源,请使用 chsrc list ", target));
|
||||
exit(1);
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 该函数来自 oh-my-mirrorz.py,由 @ccmywish 翻译为C语言,但功劳和版权属于原作者
|
||||
*/
|
||||
char*
|
||||
to_human_readable_speed (double speed)
|
||||
{
|
||||
char* scale[] = {"Byte/s", "KByte/s", "MByte/s", "GByte/s", "TByte/s"};
|
||||
int i = 0;
|
||||
while (speed > 1024.0)
|
||||
{
|
||||
i += 1;
|
||||
speed /= 1024.0;
|
||||
}
|
||||
char* buf = xy_malloc0(64);
|
||||
sprintf(buf, "%.2f %s", speed, scale[i]);
|
||||
|
||||
char* new = NULL;
|
||||
if (i <= 1 ) new = xy_str_to_red(buf);
|
||||
else
|
||||
{
|
||||
if (i == 2 && speed < 2.00) new = xy_str_to_yellow(buf);
|
||||
else new = xy_str_to_green(buf);
|
||||
}
|
||||
return new;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 测速代码参考自 https://github.com/mirrorz-org/oh-my-mirrorz/blob/master/oh-my-mirrorz.py
|
||||
* 功劳和版权属于原作者,由 @ccmywish 修改为C语言,并做了额外调整
|
||||
*
|
||||
* @return 返回测得的速度,若出错,返回-1
|
||||
*/
|
||||
double
|
||||
test_speed_url (const char* url)
|
||||
{
|
||||
char* time_sec = "6";
|
||||
|
||||
/* 现在我们切换至跳转后的链接来测速,不再使用下述判断
|
||||
if (xy_str_start_with(url, "https://registry.npmmirror"))
|
||||
{
|
||||
// 这里 npmmirror 跳转非常慢,需要1~3秒,所以我们给它留够至少8秒测速时间,否则非常不准
|
||||
time_sec = "10";
|
||||
}
|
||||
*/
|
||||
|
||||
// 我们用 —L,因为Ruby China源会跳转到其他地方
|
||||
// npmmirror 也会跳转
|
||||
char* curl_cmd = xy_strjoin(6, "curl -qsL -o ", xy_os_devnull,
|
||||
" -w \"%{http_code} %{speed_download}\" -m", time_sec ,
|
||||
" -A chsrc/" Chsrc_Version " ", url);
|
||||
|
||||
// xy_info (xy_2strjoin("chsrc: 测速 ", url));
|
||||
|
||||
char* buf = xy_getcmd (curl_cmd, 0, NULL);
|
||||
// 如果尾部有换行,删除
|
||||
buf = xy_str_strip (buf);
|
||||
|
||||
// 分隔两部分数据
|
||||
char* split = strchr(buf, ' ');
|
||||
if (split) *split = '\0';
|
||||
|
||||
// puts(buf); puts(split+1);
|
||||
int http_code = atoi(buf);
|
||||
double speed = atof(split+1);
|
||||
char* speedstr = to_human_readable_speed(speed);
|
||||
|
||||
if (200!=http_code) {
|
||||
char* httpcodestr = xy_str_to_yellow (xy_2strjoin("HTTP码 ", buf));
|
||||
puts (xy_strjoin (3, speedstr, " | ", httpcodestr));
|
||||
} else {
|
||||
puts (speedstr);
|
||||
}
|
||||
return speed;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
get_max_ele_idx_in_dbl_ary (double* array, int size)
|
||||
{
|
||||
double maxval = array[0];
|
||||
int maxidx = 0;
|
||||
|
||||
for (int i=1; i<size; i++) {
|
||||
if (array[i]>maxval) {
|
||||
maxval = array[i];
|
||||
maxidx = i;
|
||||
}
|
||||
}
|
||||
return maxidx;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动测速选择镜像站和源
|
||||
*/
|
||||
#define auto_select(s) auto_select_(s##_sources, s##_sources_n, (char*)#s+3)
|
||||
int
|
||||
auto_select_ (SourceInfo* sources, size_t size, const char* target)
|
||||
{
|
||||
if (0==size) {
|
||||
xy_error(xy_strjoin(3, "chsrc: 当前 ", target, " 无任何可用源,请联系维护者"));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
bool onlyone = false;
|
||||
if (1==size) onlyone = true;
|
||||
|
||||
double speeds[size];
|
||||
double speed = 0.0;
|
||||
for (int i=0;i<size;i++)
|
||||
{
|
||||
SourceInfo src = sources[i];
|
||||
const char* url = src.mirror->__bigfile_url;
|
||||
if (NULL==url) {
|
||||
chsrc_warn ( xy_strjoin(3, "开发者未提供 ", src.mirror->code, " 镜像站测速链接,跳过该站点"));
|
||||
speed = 0;
|
||||
} else {
|
||||
printf ("%s",xy_strjoin(3, "chsrc: 测速 ", src.mirror->site , " ... "));
|
||||
fflush(stdout);
|
||||
speed = test_speed_url (url);
|
||||
}
|
||||
speeds[i] = speed;
|
||||
}
|
||||
int fastidx = get_max_ele_idx_in_dbl_ary (speeds, size);
|
||||
|
||||
if (onlyone)
|
||||
xy_success(xy_strjoin(5, "chsrc: ", sources[fastidx].mirror->name, " 是 ", target, " 目前唯一可用镜像站,感谢他们的慷慨支持"));
|
||||
else
|
||||
xy_success (xy_2strjoin("chsrc: 最快镜像站: ", sources[fastidx].mirror->name));
|
||||
|
||||
return fastidx;
|
||||
}
|
||||
|
||||
|
||||
#define use_specific_mirror_or_auto_select(input, s) \
|
||||
(NULL!=(input)) ? find_mirror(s, input) : auto_select(s)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 用于 _setsrc 函数
|
||||
*/
|
||||
void
|
||||
chsrc_say_selection (SourceInfo* source)
|
||||
{
|
||||
xy_info (xy_strjoin(5, "chsrc: 选中镜像站: ", source->mirror->abbr, " (", source->mirror->code, ")"));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
chsrc_say_thanks (SourceInfo* source)
|
||||
{
|
||||
xy_success(xy_2strjoin("chsrc: 感谢镜像提供方: ", source->mirror->name));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
chsrc_ensure_root ()
|
||||
{
|
||||
char* euid = getenv("$EUID");
|
||||
if (NULL==euid) {
|
||||
char* buf = xy_getcmd("id -u", 0, NULL);
|
||||
if (0!=atoi(buf)) goto not_root;
|
||||
else return;
|
||||
} else {
|
||||
if (0!=atoi(euid)) goto not_root;
|
||||
else return;
|
||||
}
|
||||
not_root:
|
||||
xy_error("chsrc: 请在命令前使用 sudo 来保证必要的权限");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
chsrc_run (const char* cmd)
|
||||
{
|
||||
xy_info (xy_2strjoin ("chsrc: 运行 ", cmd));
|
||||
system(cmd);
|
||||
}
|
||||
|
||||
static void
|
||||
chsrc_check_file (const char* path)
|
||||
{
|
||||
char* cmd = NULL;
|
||||
path = xy_uniform_path (path);
|
||||
if(xy_on_windows) {
|
||||
cmd = xy_2strjoin ("type ", path);
|
||||
} else {
|
||||
cmd = xy_2strjoin ("cat ", path);
|
||||
}
|
||||
chsrc_run (cmd);
|
||||
}
|
||||
|
||||
static void
|
||||
chsrc_ensure_dir (const char* dir)
|
||||
{
|
||||
dir = xy_uniform_path (dir);
|
||||
char* mkdir_cmd = NULL;
|
||||
if (xy_on_windows) {
|
||||
mkdir_cmd = "md ";
|
||||
} else {
|
||||
mkdir_cmd = "mkdir -p ";
|
||||
}
|
||||
char* cmd = xy_2strjoin (mkdir_cmd, dir);
|
||||
cmd = xy_str_to_quietcmd (cmd);
|
||||
chsrc_run (cmd);
|
||||
}
|
||||
|
||||
static void
|
||||
chsrc_append_to_file (const char* str, const char* file)
|
||||
{
|
||||
file = xy_uniform_path (file);
|
||||
char* dir = xy_parent_dir (file);
|
||||
chsrc_ensure_dir (dir);
|
||||
|
||||
char* cmd = NULL;
|
||||
if (xy_on_windows) {
|
||||
cmd = xy_strjoin (4, "echo ", str, " >> ", file);
|
||||
} else {
|
||||
cmd = xy_strjoin (4, "echo '", str, "' >> ", file);
|
||||
}
|
||||
chsrc_run(cmd);
|
||||
}
|
||||
|
||||
static void
|
||||
chsrc_overwrite_file (const char* str, const char* file)
|
||||
{
|
||||
file = xy_uniform_path (file);
|
||||
char* dir = xy_parent_dir (file);
|
||||
chsrc_ensure_dir (dir);
|
||||
|
||||
char* cmd = NULL;
|
||||
if (xy_on_windows) {
|
||||
cmd = xy_strjoin (4, "echo ", str, " > ", file);
|
||||
} else {
|
||||
cmd = xy_strjoin (4, "echo '", str, "' > ", file);
|
||||
}
|
||||
chsrc_run(cmd);
|
||||
}
|
||||
|
||||
static void
|
||||
chsrc_backup (const char* path)
|
||||
{
|
||||
char* cmd = NULL;
|
||||
|
||||
if (xy_on_bsd)
|
||||
{
|
||||
// 似乎BSD的cp并没有 --backup='t' 选项
|
||||
cmd = xy_strjoin(5, "cp -f ", path, " ", path, ".bak");
|
||||
}
|
||||
else if (xy_on_windows) {
|
||||
// /Y 表示覆盖
|
||||
cmd = xy_strjoin(5, "copy /Y ", path, " ", path, ".bak" );
|
||||
}
|
||||
else {
|
||||
cmd = xy_strjoin(5, "cp ", path, " ", path, ".bak --backup='t'");
|
||||
}
|
||||
|
||||
chsrc_run (cmd);
|
||||
chsrc_info ( xy_strjoin (3, "备份文件名 ", path, ".bak"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Target Info */
|
||||
typedef struct {
|
||||
void (*setfn)(char* option);
|
||||
void (*getfn)(char* option);
|
||||
SourceInfo* sources;
|
||||
size_t sources_n;
|
||||
} TargetInfo;
|
||||
|
||||
#define def_target(t) TargetInfo t##_target = {t##_setsrc, t##_getsrc, t##_sources, t##_sources_n}
|
840
include/sources.h
Normal file
840
include/sources.h
Normal file
@@ -0,0 +1,840 @@
|
||||
/** ------------------------------------------------------------
|
||||
* File : sources.h
|
||||
* License : GPLv3
|
||||
* Authors : Aoran Zeng <ccmywish@qq.com>
|
||||
* Created on : <2023-08-29>
|
||||
* Last modified : <2024-04-18>
|
||||
*
|
||||
* sources:
|
||||
*
|
||||
* 镜像站与源信息
|
||||
* ------------------------------------------------------------*/
|
||||
|
||||
typedef struct {
|
||||
const char* code; // 用于用户指定镜像站
|
||||
const char* abbr;
|
||||
const char* name;
|
||||
const char* site;
|
||||
const char* __bigfile_url; // 用于对该镜像站测速
|
||||
} MirrorInfo;
|
||||
|
||||
// #define Big_File_ubuntu "/indices/md5sums.gz" 这个是错的
|
||||
#define Big_File_ctan "/systems/texlive/Images/texlive.iso" // 4.8GB
|
||||
#define Big_File_debian "/ls-lR.gz" // 13.9 MB
|
||||
#define Big_File_archlinux "/iso/latest/archlinux-x86_64.iso" // 800MB 左右
|
||||
#define Big_File_deepin "/20.9/deepin-desktop-community-20.9-amd64.iso" // 4GB左右
|
||||
|
||||
|
||||
/**
|
||||
* 教育网镜像
|
||||
*
|
||||
* 我们目前根据 https://github.com/mirrorz-org/oh-my-mirrorz 挑选速度前10位
|
||||
*/
|
||||
MirrorInfo
|
||||
MirrorZ = {"mirrorz", "MirrorZ", "MirrorZ 校园网镜像站", "https://mirrors.cernet.edu.cn/", NULL},
|
||||
|
||||
Tuna = {"tuna", "TUNA", "清华大学开源软件镜像站", "https://mirrors.tuna.tsinghua.edu.cn/",
|
||||
"https://mirrors.tuna.tsinghua.edu.cn/speedtest/1000mb.bin"},
|
||||
|
||||
Sjtug_Zhiyuan = {"sjtu", "SJTUG-zhiyuan", "上海交通大学致远镜像站", "https://mirrors.sjtug.sjtu.edu.cn/",
|
||||
"https://mirrors.sjtug.sjtu.edu.cn/ctan" Big_File_ctan},
|
||||
|
||||
Zju = {"zju", "ZJU", "浙江大学开源软件镜像站", "https://mirrors.zju.edu.cn/",
|
||||
"https://mirrors.zju.edu.cn/debian" Big_File_debian},
|
||||
|
||||
Lzuoss = {"lzu", "LZUOSS", "兰州大学开源社区镜像站", "https://mirror.lzu.edu.cn/",
|
||||
"https://mirror.lzu.edu.cn/CTAN" Big_File_ctan},
|
||||
|
||||
Jlu = {"jlu", "JLU", "吉林大学开源镜像站", "https://mirrors.jlu.edu.cn/",
|
||||
"https://mirrors.jlu.edu.cn/_static/speedtest.bin"},
|
||||
|
||||
Bfsu = {"bfsu", "BFSU", "北京外国语大学开源软件镜像站","https://mirrors.bfsu.edu.cn/",
|
||||
"https://mirrors.bfsu.edu.cn/speedtest/1000mb.bin"},
|
||||
|
||||
Pku = {"pku", "PKU", "北京大学开源镜像站", "https://mirrors.pku.edu.cn/",
|
||||
"https://mirrors.pku.edu.cn/debian" Big_File_debian},
|
||||
|
||||
Bjtu = {"bjtu", "BJTU", "北京交通大学自由与开源软件镜像站", "https://mirror.bjtu.edu.cn/",
|
||||
"https://mirror.bjtu.edu.cn/archlinux" Big_File_archlinux},
|
||||
|
||||
Sustech = {"sustech", "SUSTech", "南方科技大学开源软件镜像站", "https://mirrors.sustech.edu.cn/",
|
||||
"https://mirrors.sustech.edu.cn/site/speedtest/1000mb.bin"},
|
||||
|
||||
Ustc = {"ustc", "USTC", "中国科学技术大学开源镜像站", "https://mirrors.ustc.edu.cn/",
|
||||
"https://mirrors.ustc.edu.cn/CTAN" Big_File_ctan},
|
||||
|
||||
// 速度暂时处于10位以后,但是目前可用的源
|
||||
Nju = {"nju", "NJU", "南京大学开源镜像站", "https://mirrors.nju.edu.cn/",
|
||||
"https://mirrors.nju.edu.cn/archlinux" Big_File_archlinux};
|
||||
|
||||
|
||||
// @ccmywish: [2023-09-05] 我只使用了不到5次,重庆大学镜像站就把我的ip封杀了,对用户来说封杀策略过严,暂时不可靠,暂时不用
|
||||
//
|
||||
// Cqu = {"cqu", "CQU", "重庆大学开源软件镜像站", "https://mirrors.cqu.edu.cn/",
|
||||
// "https://mirrors.cqu.edu.cn/speedtest/1000mb.bin"};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 商业公司提供的源
|
||||
*
|
||||
* @warning 腾讯软件源中,有很多链接都已失效,请仔细检查
|
||||
*/
|
||||
MirrorInfo
|
||||
Ali = {"ali", "Ali OPSX", "阿里巴巴开源镜像站", "https://developer.aliyun.com/mirror/",
|
||||
"https://mirrors.aliyun.com/deepin-cd" Big_File_deepin},
|
||||
|
||||
Tencent = {"tencent", "Tencent", "腾讯软件源", "https://mirrors.tencent.com/",
|
||||
"https://mirrors.cloud.tencent.com/debian" Big_File_debian},
|
||||
|
||||
Huawei = {"huawei", "Huawei Cloud", "华为开源镜像站", "https://mirrors.huaweicloud.com/",
|
||||
"https://mirrors.huaweicloud.com/debian/" Big_File_debian },
|
||||
|
||||
Netease = {"netease", "Netease", "网易开源镜像站", "https://mirrors.163.com/",
|
||||
"https://mirrors.163.com/deepin-cd" Big_File_deepin},
|
||||
|
||||
Sohu = {"sohu", "SOHU", "搜狐开源镜像站", "https://mirrors.sohu.com/",
|
||||
"https://mirrors.sohu.com/deepin-cd" Big_File_deepin},
|
||||
|
||||
Api7 = {"api7", "api7.ai", "深圳支流科技有限公司", "https://www.apiseven.com/", NULL};
|
||||
|
||||
// 开源社区
|
||||
MirrorInfo
|
||||
RubyChina = {"rubychina", "RubyChina", "Ruby China 社区", "https://gems.ruby-china.com/",
|
||||
"https://gems.ruby-china.com/rubygems/gems/nokogiri-1.15.0-java.gem"}, // 9.9 MB
|
||||
|
||||
NpmMirror = {"npmmirror", "npmmirror", "npmmirror (阿里云赞助)", "https://npmmirror.com/",
|
||||
// 注意,这个是跳转后的地址,不确定未来会不会改变
|
||||
"https://cdn.npmmirror.com/packages/%40tensorflow/tfjs/4.10.0/tfjs-4.10.0.tgz"}, // 29MB
|
||||
|
||||
GoProxyCN = {"goproxy.cn", "Goproxy.cn", "Goproxy.cn (七牛云赞助)", "https://goproxy.cn/",
|
||||
"https://goproxy.cn/github.com/aws/aws-sdk-go/@v/v1.45.2.zip"}, // 30 MB
|
||||
|
||||
GoProxyIO = {"goproxy.io", "GOPROXY.IO", "GOPROXY.IO", "https://goproxy.io/",
|
||||
"https://goproxy.io/github.com/aws/aws-sdk-go/@v/v1.45.2.zip"}, // 30 MB
|
||||
|
||||
NugetOrg = {"nuget.org", "NuGet Org", "Nuget Organization", "https://www.nuget.org/", NULL},
|
||||
EmacsChina = {"emacschina", "EmacsChina", "Emacs China 社区", "https://elpamirror.emacs-china.org/", NULL};
|
||||
|
||||
|
||||
MirrorInfo
|
||||
Upstream = {"upstream", "Upstream", "上游默认源", NULL, NULL};
|
||||
|
||||
|
||||
MirrorInfo*
|
||||
available_mirrors[] = {
|
||||
&MirrorZ, &Tuna, &Sjtug_Zhiyuan, &Zju, &Lzuoss, &Jlu, &Bfsu, &Pku, &Bjtu, &Sustech, &Ustc, &Nju, // &Cqu,
|
||||
&Ali, &Tencent, &Huawei, &Netease, &Sohu, &Api7,
|
||||
&RubyChina, &EmacsChina, &NpmMirror, &GoProxyCN, &GoProxyIO,
|
||||
// 暂不支持 &NugetOrg
|
||||
|
||||
// 不要列出 &Upstream
|
||||
};
|
||||
|
||||
|
||||
typedef struct {
|
||||
const MirrorInfo* mirror;
|
||||
const char* url;
|
||||
} SourceInfo;
|
||||
|
||||
|
||||
/**
|
||||
* 源信息
|
||||
*
|
||||
* @note 我们要求每个源最好情况下
|
||||
* 1. 至少有一个教育网镜像
|
||||
* 2. 至少有一个商业公司或开源社区维护的镜像
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* 2024-04-18 更新
|
||||
*
|
||||
* @note
|
||||
* 下面的源,并不都实现正确,
|
||||
* BFSU 和 Tuna 以及 阿里的镜像都有问题,会循环遍历一个gem的所有版本,导致安装时间相当长
|
||||
*
|
||||
* @note
|
||||
* 2024-04-18: @ccmywish: 华为云镜像正确可用
|
||||
*
|
||||
* @note 网络情况
|
||||
* 若实现正确:
|
||||
* 1. 目前北外最快最稳定
|
||||
* 2. 腾讯挺快,个别时候不稳定,但稳定时能达到4.5MB甚至以上
|
||||
* 3. tuna 有时快有时慢,不稳定,一般在3MB以下
|
||||
* 4. rubychina 有时快有时慢,快时一般在 2MB以下,慢时一般在1MB以下
|
||||
* 5. 阿里云最不稳定,经常最慢
|
||||
*/
|
||||
static SourceInfo
|
||||
pl_ruby_sources[] = {
|
||||
{&Tencent, "https://mirrors.tencent.com/rubygems/"},
|
||||
{&RubyChina, "https://gems.ruby-china.com/"},
|
||||
{&Huawei, "https://mirrors.huaweicloud.com/repository/rubygems/"}
|
||||
|
||||
// {&Bfsu, "https://mirrors.bfsu.edu.cn/rubygems/"},
|
||||
// {&Tuna, "https://mirrors.tuna.tsinghua.edu.cn/rubygems/"},
|
||||
// {&Ali, "https://mirrors.aliyun.com/rubygems/"},
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 2024-04-18 更新
|
||||
*
|
||||
* @note 不要添加Zju,浙大的pypi在校外访问会自动转向Tuna
|
||||
*/
|
||||
pl_python_sources[] = {
|
||||
{&Bfsu, "https://mirrors.bfsu.edu.cn/pypi/web/simple"},
|
||||
{&Lzuoss, "https://mirror.lzu.edu.cn/pypi/web/simple"},
|
||||
{&Jlu, "https://mirrors.jlu.edu.cn/pypi/web/simple"},
|
||||
{&Sjtug_Zhiyuan, "https://mirror.sjtu.edu.cn/pypi/web/simple"},
|
||||
{&Tuna, "https://pypi.tuna.tsinghua.edu.cn/simple"},
|
||||
{&Ali, "https://mirrors.aliyun.com/pypi/simple/"},
|
||||
{&Tencent, "https://mirrors.cloud.tencent.com/pypi/simple"},
|
||||
{&Huawei, "https://mirrors.huaweicloud.com/repository/pypi/simple"},
|
||||
// {&Netease, "https://mirrors.163.com/.help/pypi.html"} // 不用,24小时更新一次
|
||||
},
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 2024-04-18 更新
|
||||
*
|
||||
* Sjtug, Tuna, Lzuoss, Jlu, Bfsu, 网易,搜狐 都没有
|
||||
*
|
||||
* @note 腾讯软件源虽然有npm的名,但名存实亡
|
||||
*/
|
||||
pl_nodejs_sources[] = {
|
||||
{&NpmMirror, "https://registry.npmmirror.com"},
|
||||
{&Huawei, "https://mirrors.huaweicloud.com/repository/npm/"},
|
||||
{&Zju, "https://mirrors.zju.edu.cn/npm"}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 2023-09-05 更新
|
||||
*
|
||||
* 参考: https://help.mirrors.cernet.edu.cn/CPAN/
|
||||
*/
|
||||
pl_perl_sources[] = {
|
||||
{&Bfsu, "https://mirrors.bfsu.edu.cn/CPAN/"},
|
||||
{&Tuna, "https://mirrors.tuna.tsinghua.edu.cn/CPAN/"},
|
||||
{&Bjtu, "https://mirror.bjtu.edu.cn/cpan/"},
|
||||
{&Ali, "https://mirrors.aliyun.com/CPAN/"},
|
||||
{&Lzuoss, "https://mirror.lzu.edu.cn/CPAN/"}
|
||||
},
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 2024-04-18 更新
|
||||
*
|
||||
* @note 缺少教育网或开源社区软件源
|
||||
*/
|
||||
pl_php_sources[] = {
|
||||
{&Ali, "https://mirrors.aliyun.com/composer/"},
|
||||
{&Tencent, "https://mirrors.tencent.com/composer/"},
|
||||
{&Huawei, "https://mirrors.huaweicloud.com/repository/php/"}
|
||||
},
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 2023-09-27 更新
|
||||
*
|
||||
* @note 目前只有唯一一个源
|
||||
*/
|
||||
pl_lua_sources[] = {
|
||||
{&Api7, "https://luarocks.cn"},
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 2024-04-18 更新
|
||||
*
|
||||
* @note 缺少教育网软件源
|
||||
*/
|
||||
pl_go_sources[] = {
|
||||
{&GoProxyCN, "https://goproxy.cn"},
|
||||
{&Ali, "https://mirrors.aliyun.com/goproxy/"},
|
||||
{&Huawei, "https://mirrors.huaweicloud.com/goproxy/"},
|
||||
{&GoProxyIO, "https://goproxy.io"}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 2023-09-05 更新
|
||||
*
|
||||
* @note 缺少商业公司或开源社区软件源
|
||||
*
|
||||
* @note 以下都支持稀疏索引,我们换源时都将默认添加 `sparse+`
|
||||
*/
|
||||
pl_rust_sources[] = {
|
||||
{&Sjtug_Zhiyuan, "https://mirrors.sjtug.sjtu.edu.cn/crates.io-index/"},
|
||||
{&Tuna, "https://mirrors.tuna.tsinghua.edu.cn/crates.io-index/"},
|
||||
{&Bfsu, "https://mirrors.bfsu.edu.cn/crates.io-index/"},
|
||||
{&Ustc, "https://mirrors.ustc.edu.cn/crates.io-index/"},
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 2024-04-18 更新
|
||||
*
|
||||
* @note 缺少教育网或开源社区软件源
|
||||
*/
|
||||
pl_java_sources[] = {
|
||||
{&Ali, "https://maven.aliyun.com/repository/public/"},
|
||||
{&Huawei, "https://mirrors.huaweicloud.com/repository/maven/"},
|
||||
{&Netease, "http://mirrors.163.com/maven/repository/maven-public/"} // 网易的24小时更新一次
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 2023-09-10 更新
|
||||
*
|
||||
* @note 不太好换,且用户可能不多,我们暂时只给用户提供文档
|
||||
*/
|
||||
pl_clojure_sources[] = {
|
||||
{&Tuna, "https://mirrors.tuna.tsinghua.edu.cn/help/clojars/"},
|
||||
{&Ustc, "https://mirrors.ustc.edu.cn/help/clojars.html"}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 2024-04-18 更新
|
||||
*
|
||||
* @note 暂时未实现该换源功能,可参照
|
||||
* https://mirrors.huaweicloud.com/mirrorDetail/5ebf85de07b41baf6d0882ab?mirrorName=nuget&catalog=language
|
||||
*/
|
||||
pl_dotnet_sources[] = {
|
||||
{&NugetOrg, "https://www.nuget.org/api/v2/"},
|
||||
{&Huawei, "https://mirrors.huaweicloud.com/repository/nuget/v3"}
|
||||
},
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 2023-09-10 更新
|
||||
*
|
||||
* @note 我们这里挑选的必须也支持 Flutter
|
||||
*
|
||||
* 我们将会在setsrc函数中生成
|
||||
* 1. https://mirrors.tuna.tsinghua.edu.cn/dart-pub
|
||||
* 2. https://mirrors.tuna.tsinghua.edu.cn/flutter
|
||||
*/
|
||||
pl_dart_sources[] = {
|
||||
// {&Sjtug_Zhiyuan, "https://mirror.sjtu.edu.cn/"}, // 不确定SJTUG的flutter镜像给的对不对
|
||||
{&Tuna, "https://mirrors.tuna.tsinghua.edu.cn/"},
|
||||
{&Tencent, "https://mirrors.cloud.tencent.com/"},
|
||||
{&Nju, "https://mirror.nju.edu.cn/"}
|
||||
},
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 2023-09-10 更新
|
||||
*/
|
||||
pl_haskell_sources[] = {
|
||||
{&Tuna, "https://mirrors.tuna.tsinghua.edu.cn/hackage"},
|
||||
{&Bfsu, "https://mirrors.bfsu.edu.cn/hackage"},
|
||||
{&Nju, "https://mirror.nju.edu.cn/hackage"},
|
||||
{&Ustc, "https://mirrors.ustc.edu.cn/hackage"}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 2023-09-15 更新
|
||||
*/
|
||||
pl_ocaml_sources[] = {
|
||||
{&Sjtug_Zhiyuan, "https://mirrors.sjtug.sjtu.edu.cn/git/opam-repository.git"}
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 2023-09-04 更新
|
||||
*
|
||||
* @note 以下注释的,是不含有bioconductor的镜像站,
|
||||
* 我们在换cran的同时,也直接帮助用户换bioconductor
|
||||
*/
|
||||
pl_r_sources[] = {
|
||||
{&Sjtug_Zhiyuan, "https://mirrors.sjtug.sjtu.edu.cn/cran/"},
|
||||
// {&Ali, "https://mirrors.aliyun.com/CRAN/"},
|
||||
{&Tuna, "https://mirrors.tuna.tsinghua.edu.cn/CRAN/"},
|
||||
// {&Sustech, "https://mirrors.sustech.edu.cn/CRAN"},
|
||||
// {&Bfsu, "https://mirrors.bfsu.edu.cn/CRAN/"},
|
||||
// {&Bjtu, "https://mirror.bjtu.edu.cn/cran/"},
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 2023-09-05 更新
|
||||
*
|
||||
* @note 缺少商业公司或开源社区软件源
|
||||
*/
|
||||
pl_julia_sources[] = {
|
||||
{&Sjtug_Zhiyuan, "https://mirrors.sjtug.sjtu.edu.cn/julia"},
|
||||
{&Pku, "https://mirrors.pku.edu.cn/julia"},
|
||||
{&Nju, "https://mirror.nju.edu.cn/julia"}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 2024-04-18 更新
|
||||
*/
|
||||
static SourceInfo
|
||||
os_ubuntu_sources[] = {
|
||||
{&Ali, "https://mirrors.aliyun.com/ubuntu"},
|
||||
{&Bfsu, "https://mirrors.bfsu.edu.cn/ubuntu"},
|
||||
{&Ustc, "https://mirrors.ustc.edu.cn/ubuntu"},
|
||||
{&Tuna, "https://mirrors.tuna.tsinghua.edu.cn/ubuntu"},
|
||||
{&Tencent, "https://mirrors.tencent.com/ubuntu"},
|
||||
{&Huawei, "https://mirrors.huaweicloud.com/ubuntu"},
|
||||
{&Netease, "https://mirrors.163.com/ubuntu"},
|
||||
{&Sohu, "https://mirrors.sohu.com/ubuntu"}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 2023-09-29 更新
|
||||
*
|
||||
* @note: 实际上镜像站里的内容和Ubuntu的不太一样
|
||||
*/
|
||||
os_mint_sources[] = {
|
||||
{&MirrorZ, "https://mirrors.cernet.edu.cn/linuxmint/"},
|
||||
{&Ali, "http://mirrors.aliyun.com/linuxmint-packages/"},
|
||||
{&Netease, "https://mirrors.163.com/linuxmint/packages/"},
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 2023-09-06 更新
|
||||
*
|
||||
* TODO: 1. 源并不完整,且未经测试是否有效
|
||||
*/
|
||||
os_deepin_sources[] = {
|
||||
{&Ali, "https://mirrors.aliyun.com/deepin"},
|
||||
{&Bfsu, "https://mirrors.bfsu.edu.cn/deepin"},
|
||||
{&Ustc, "https://mirrors.ustc.edu.cn/deepin"},
|
||||
{&Tuna, "https://mirrors.tuna.tsinghua.edu.cn/deepin"},
|
||||
{&Tencent, "https://mirrors.tencent.com/deepin"},
|
||||
{&Netease, "https://mirrors.163.com/deepin"},
|
||||
{&Sohu, "https://mirrors.sohu.com/deepin"}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 2023-09-01 更新
|
||||
*
|
||||
* TODO: 1. 源并不完整,且未经测试是否有效
|
||||
*/
|
||||
os_debian_sources[] = {
|
||||
{&Ali, "https://mirrors.aliyun.com/debian"},
|
||||
{&Bfsu, "https://mirrors.bfsu.edu.cn/debian"},
|
||||
{&Ustc, "https://mirrors.ustc.edu.cn/debian"},
|
||||
{&Tuna, "https://mirrors.tuna.tsinghua.edu.cn/debian"},
|
||||
{&Tencent, "https://mirrors.tencent.com/debian"},
|
||||
{&Netease, "https://mirrors.163.com/debian"},
|
||||
{&Sohu, "https://mirrors.sohu.com/debian"}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 2023-09-02 更新
|
||||
*
|
||||
* TODO: 1. 源并不完整,且未经测试是否有效
|
||||
*/
|
||||
os_fedora_sources[] = {
|
||||
{&Ali, "https://mirrors.aliyun.com/fedora"},
|
||||
{&Bfsu, "https://mirrors.bfsu.edu.cn/fedora"},
|
||||
{&Ustc, "https://mirrors.ustc.edu.cn/fedora"},
|
||||
{&Tuna, "https://mirrors.tuna.tsinghua.edu.cn/fedora"},
|
||||
{&Tencent, "https://mirrors.tencent.com/fedora"},
|
||||
{&Netease, "https://mirrors.163.com/fedora"},
|
||||
{&Sohu, "https://mirrors.sohu.com/fedora"}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 2024-04-18 更新
|
||||
*
|
||||
* TODO: 未经测试是否有效
|
||||
*/
|
||||
os_kali_sources[] = {
|
||||
{&Ali, "https://mirrors.aliyun.com/kali"},
|
||||
{&Bfsu, "https://mirrors.bfsu.edu.cn/kali"},
|
||||
{&Ustc, "https://mirrors.ustc.edu.cn/kali"},
|
||||
{&Tuna, "https://mirrors.tuna.tsinghua.edu.cn/kali"},
|
||||
{&Tencent, "https://mirrors.tencent.com/kali"},
|
||||
{&Huawei, "https://mirrors.huaweicloud.com/kali"},
|
||||
{&Netease, "https://mirrors.163.com/kali"},
|
||||
{&Sohu, "https://mirrors.sohu.com/kali"}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 2024-04-18 更新
|
||||
*
|
||||
* TODO: 源并不完整,且未经测试是否有效
|
||||
*/
|
||||
os_arch_sources[] = {
|
||||
{&Ali, "https://mirrors.aliyun.com/"},
|
||||
{&Bfsu, "https://mirrors.bfsu.edu.cn/"},
|
||||
{&Ustc, "https://mirrors.ustc.edu.cn/"},
|
||||
{&Tuna, "https://mirrors.tuna.tsinghua.edu.cn/"},
|
||||
{&Tencent, "https://mirrors.tencent.com/"},
|
||||
{&Huawei, "https://mirrors.huaweicloud.com/archlinux/"},
|
||||
{&Netease, "https://mirrors.163.com/"},
|
||||
{&Sohu, "https://mirrors.sohu.com/"}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 2023-09-05 更新
|
||||
*
|
||||
* TODO: 1. 源并不完整,且未经测试是否有效
|
||||
*/
|
||||
os_gentoo_sources[] = {
|
||||
{&Ali, "mirrors.aliyun.com"},
|
||||
{&Bfsu, "mirrors.bfsu.edu.cn"},
|
||||
{&Ustc, "mirrors.ustc.edu.cn"},
|
||||
{&Tuna, "mirrors.tuna.tsinghua.edu.cn"},
|
||||
{&Tencent, "mirrors.tencent.com"},
|
||||
{&Netease, "mirrors.163.com"},
|
||||
{&Sohu, "mirrors.sohu.com"}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 2023-09-17 更新
|
||||
*
|
||||
* TODO: 1. 源并不完整,且未经测试是否有效
|
||||
*/
|
||||
os_opensuse_sources[] = {
|
||||
{&Ali, "https://mirrors.aliyun.com/opensuse"},
|
||||
{&Bfsu, "https://mirrors.bfsu.edu.cn/opensuse"},
|
||||
{&Ustc, "https://mirrors.ustc.edu.cn/opensuse"},
|
||||
{&Tuna, "https://mirrors.tuna.tsinghua.edu.cn/opensuse"},
|
||||
{&Tencent, "https://mirrors.tencent.com/opensuse"},
|
||||
{&Netease, "https://mirrors.163.com/opensuse"},
|
||||
{&Sohu, "https://mirrors.sohu.com/opensuse"}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 2024-04-18 更新
|
||||
*
|
||||
* TODO: 源并不完整,且未经测试是否有效
|
||||
*/
|
||||
os_msys2_sources[] = {
|
||||
{&Ali, "https://mirrors.aliyun.com/msys2"},
|
||||
{&Bfsu, "https://mirrors.bfsu.edu.cn/msys2"},
|
||||
{&Ustc, "https://mirrors.ustc.edu.cn/msys2"},
|
||||
{&Tuna, "https://mirrors.tuna.tsinghua.edu.cn/msys2"},
|
||||
{&Tencent, "https://mirrors.tencent.com/msys2"},
|
||||
{&Huawei, "https://mirrors.huaweicloud.com/msys2"},
|
||||
{&Netease, "https://mirrors.163.com/msys2"},
|
||||
{&Sohu, "https://mirrors.sohu.com/msys2"}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 2023-09-24 更新
|
||||
*/
|
||||
os_rocky_sources[] = {
|
||||
{&Sjtug_Zhiyuan, "https://mirror.sjtu.edu.cn/rocky"},
|
||||
{&Sustech, "https://mirrors.sustech.edu.cn/rocky-linux"},
|
||||
{&Zju, "https://mirrors.zju.edu.cn/rocky"},
|
||||
{&Lzuoss, "https://mirror.lzu.edu.cn/rocky"},
|
||||
{&Sohu, "https://mirrors.sohu.com/Rocky"},
|
||||
{&Netease, "https://mirrors.163.com/rocky"},
|
||||
{&Ali, "https://mirrors.aliyun.com/rockylinux"},
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 2024-04-18 更新
|
||||
*/
|
||||
os_alpine_sources[] = {
|
||||
{&Tuna, "https://mirrors.tuna.tsinghua.edu.cn/alpine"},
|
||||
{&Sjtug_Zhiyuan, "https://mirrors.sjtug.sjtu.edu.cn/alpine"},
|
||||
{&Sustech, "https://mirrors.sustech.edu.cn/alpine"},
|
||||
{&Zju, "https://mirrors.zju.edu.cn/alpine"},
|
||||
{&Lzuoss, "https://mirror.lzu.edu.cn/alpine"},
|
||||
{&Ali, "https://mirrors.aliyun.com/alpine"},
|
||||
{&Tencent, "https://mirrors.cloud.tencent.com/alpine"},
|
||||
{&Huawei, "https://mirrors.huaweicloud.com/alpine/"}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 2023-09-24 更新
|
||||
*/
|
||||
os_void_sources[] = {
|
||||
{&Tuna, "https://mirrors.tuna.tsinghua.edu.cn/voidlinux"},
|
||||
{&Sjtug_Zhiyuan, "https://mirror.sjtu.edu.cn/voidlinux"},
|
||||
{&Bfsu, "https://mirrors.bfsu.edu.cn/voidlinux"}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 2023-09-29 更新
|
||||
*/
|
||||
os_solus_sources[] = {
|
||||
{&Tuna, "https://mirrors.tuna.tsinghua.edu.cn/solus/packages/shannon/eopkg-index.xml.xz"},
|
||||
{&Bfsu, "https://mirrors.bfsu.edu.cn/solus/packages/shannon/eopkg-index.xml.xz"},
|
||||
{&Nju, "https://mirror.nju.edu.cn/solus/packages/shannon/eopkg-index.xml.xz"}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 2023-09-29 更新
|
||||
*/
|
||||
os_linuxlite_sources[] = {
|
||||
{&Sjtug_Zhiyuan, "https://mirrors.sjtug.sjtu.edu.cn/linuxliteos/"}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 2023-09-29 更新
|
||||
*/
|
||||
os_trisquel_sources[] = {
|
||||
{&Ali, "https://mirrors.aliyun.com/trisquel/"},
|
||||
{&MirrorZ, "https://mirrors.cernet.edu.cn/trisquel/"},
|
||||
{&Nju, "https://mirror.nju.edu.cn/trisquel/"},
|
||||
{&Ustc, "https://mirrors.ustc.edu.cn/trisquel/"}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 2023-09-29 更新
|
||||
*/
|
||||
os_raspberrypi_sources[] = {
|
||||
{&MirrorZ, "https://help.mirrors.cernet.edu.cn/raspberrypi/"},
|
||||
{&Tuna, "https://mirrors.tuna.tsinghua.edu.cn/raspberrypi/"},
|
||||
{&Bfsu, "https://mirrors.bfsu.edu.cn/raspberrypi/"},
|
||||
{&Ustc, "https://mirrors.ustc.edu.cn/raspberrypi/"},
|
||||
{&Sjtug_Zhiyuan, "https://mirrors.sjtug.sjtu.edu.cn/raspberrypi/"},
|
||||
{&Sustech, "https://mirrors.sustech.edu.cn/raspberrypi/"}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 2023-09-27 更新
|
||||
*
|
||||
* @note 该源需要 FreeBSD 中文社区积极参与维护
|
||||
*
|
||||
* @ccmywish: [2023-09-24] 以下三个USTC, NJU, Netease 均维护了 freebsd-pkg freebsd-ports
|
||||
* @ccmywish: [2023-09-27] 请务必保持Nju前面有至少一个镜像,原因请查看 freebsd 的换源函数
|
||||
*/
|
||||
os_freebsd_sources[] = {
|
||||
{&Ustc, "mirrors.ustc.edu.cn"},
|
||||
{&Nju, "mirror.nju.edu.cn"},
|
||||
{&Netease, "mirrors.163.com"},
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 2023-09-05 更新
|
||||
*
|
||||
* TODO: 1. 源并不完整,且未经测试是否有效
|
||||
*/
|
||||
os_netbsd_sources[] = {
|
||||
{&Ali, "https://mirrors.aliyun.com/pkgsrc/packages/NetBSD/"},
|
||||
{&Bfsu, "https://mirrors.bfsu.edu.cn/pkgsrc/packages/NetBSD/"},
|
||||
{&Ustc, "https://mirrors.ustc.edu.cn/pkgsrc/packages/NetBSD/"},
|
||||
{&Tuna, "https://mirrors.tuna.tsinghua.edu.cn/pkgsrc/packages/NetBSD/"},
|
||||
{&Tencent, "https://mirrors.tencent.com/pkgsrc/packages/NetBSD/"},
|
||||
{&Netease, "https://mirrors.163.com/pkgsrc/packages/NetBSD/"},
|
||||
{&Sohu, "https://mirrors.sohu.com/pkgsrc/packages/NetBSD/"}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 2023-09-02 更新
|
||||
*
|
||||
* TODO: 1. 源并不完整,且未经测试是否有效
|
||||
*/
|
||||
os_openbsd_sources[] = {
|
||||
{&Ali, "https://mirrors.aliyun.com/OpenBSD/"},
|
||||
{&Bfsu, "https://mirrors.bfsu.edu.cn/OpenBSD/"},
|
||||
{&Ustc, "https://mirrors.ustc.edu.cn/OpenBSD/"},
|
||||
{&Tuna, "https://mirrors.tuna.tsinghua.edu.cn/OpenBSD/"},
|
||||
{&Tencent, "https://mirrors.tencent.com/OpenBSD/"},
|
||||
{&Netease, "https://mirrors.163.com/OpenBSD/"},
|
||||
{&Sohu, "https://mirrors.sohu.com/OpenBSD/"}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 2023-09-06 更新
|
||||
*
|
||||
* TODO: 1. 源并不完整,且未经测试是否有效
|
||||
*/
|
||||
os_openeuler_sources[] = {
|
||||
{&Ali, "https://mirrors.aliyun.com/openeuler/"},
|
||||
{&Bfsu, "https://mirrors.bfsu.edu.cn/openeuler/"},
|
||||
{&Ustc, "https://mirrors.ustc.edu.cn/openeuler/"},
|
||||
{&Tuna, "https://mirrors.tuna.tsinghua.edu.cn/openeuler/"},
|
||||
{&Tencent, "https://mirrors.tencent.com/openeuler/"},
|
||||
{&Netease, "https://mirrors.163.com/openeuler/"},
|
||||
{&Sohu, "https://mirrors.sohu.com/openeuler/"}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 2023-09-29 更新
|
||||
*/
|
||||
os_openkylin_sources[] = {
|
||||
{&Upstream, "https://archive.openkylin.top/openkylin/"},
|
||||
{&Ali, "https://mirrors.aliyun.com/openkylin/"},
|
||||
{&Netease, "https://mirrors.163.com/openkylin/"},
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 2024-04-18 更新
|
||||
*
|
||||
* TODO: 未经测试是否有效
|
||||
*/
|
||||
os_ros_sources[] = {
|
||||
{&Ali, "https://mirrors.aliyun.com"},
|
||||
{&Bfsu, "https://mirrors.bfsu.edu.cn"},
|
||||
{&Ustc, "https://mirrors.ustc.edu.cn"},
|
||||
{&Tuna, "https://mirrors.tuna.tsinghua.edu.cn"},
|
||||
{&Tencent, "https://mirrors.tencent.com"},
|
||||
{&Huawei, "https://mirrors.huaweicloud.com"},
|
||||
{&Netease, "https://mirrors.163.com"},
|
||||
{&Sohu, "https://mirrors.sohu.com"}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 2023-09-10 更新
|
||||
*
|
||||
* TODO: 1. 暂未添加商业公司源
|
||||
*/
|
||||
static SourceInfo
|
||||
wr_tex_sources[] = {
|
||||
{&Sjtug_Zhiyuan, "https://mirrors.sjtug.sjtu.edu.cn/ctan/systems/texlive/tlnet"},
|
||||
{&Tuna, "https://mirrors.tuna.tsinghua.edu.cn/CTAN/systems/texlive/tlnet"},
|
||||
{&Bfsu, "https://mirrors.bfsu.edu.cn/CTAN/systems/texlive/tlnet"},
|
||||
{&Lzuoss, "https://mirror.lzu.edu.cn/CTAN/systems/texlive/tlnet"},
|
||||
{&Jlu, "https://mirrors.jlu.edu.cn/CTAN/systems/texlive/tlnet"},
|
||||
{&Sustech, "https://mirrors.sustech.edu.cn/CTAN/systems/texlive/tlnet"}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 2023-09-10 更新
|
||||
*
|
||||
* @note Emacs用户往往只需要一次性换源,只会极少次调用 chsrc,我们只给用户提供文档
|
||||
*/
|
||||
wr_emacs_sources[] = {
|
||||
{&Sjtug_Zhiyuan, "https://mirrors.sjtug.sjtu.edu.cn/docs/emacs-elpa"},
|
||||
{&Tuna, "https://mirrors.tuna.tsinghua.edu.cn/help/elpa/"},
|
||||
{&Bfsu, "https://mirrors.bfsu.edu.cn/help/elpa/"},
|
||||
{&Ustc, "https://mirrors.ustc.edu.cn/help/elpa.html"},
|
||||
{&Zju, "https://mirrors.zju.edu.cn/docs/elpa/"},
|
||||
{&EmacsChina, "https://elpamirror.emacs-china.org/"}
|
||||
},
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 2023-09-10 更新
|
||||
*
|
||||
* @note 1. 这些链接将会在setsrc函数中补充完整
|
||||
* 2. 不确定 Sustech 能否工作
|
||||
*/
|
||||
wr_brew_sources[] = {
|
||||
{&Tuna, "https://mirrors.tuna.tsinghua.edu.cn/"},
|
||||
{&Bfsu, "https://mirrors.bfsu.edu.cn/"},
|
||||
{&Zju, "https://mirrors.zju.edu.cn/"},
|
||||
{&Sustech, "https://mirrors.sustech.edu.cn/"}
|
||||
},
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 2023-09-11 更新
|
||||
*
|
||||
* @note 目前只有一个源
|
||||
*/
|
||||
wr_flathub_sources[] = {
|
||||
{&Sjtug_Zhiyuan, "https://mirror.sjtu.edu.cn/flathub"},
|
||||
},
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 2023-09-22 更新
|
||||
*
|
||||
* @note 1. 目前只有一个源
|
||||
* 2. 这些链接将会在setsrc函数中补充完整
|
||||
*/
|
||||
wr_nix_sources[] = {
|
||||
{&Bfsu, "https://mirrors.bfsu.edu.cn/nix-channels/"}
|
||||
},
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 2023-09-11 更新
|
||||
*
|
||||
* @note 目前只有一个源
|
||||
*/
|
||||
wr_guix_sources[] = {
|
||||
{&Sjtug_Zhiyuan, "https://mirror.sjtu.edu.cn/git/guix.git"}
|
||||
},
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 2023-09-10 更新
|
||||
*
|
||||
* @note 这些链接将会在setsrc函数中补充完整
|
||||
*/
|
||||
wr_anaconda_sources[] = {
|
||||
{&Tuna, "https://mirrors.tuna.tsinghua.edu.cn/anaconda/"},
|
||||
{&Bfsu, "https://mirrors.bfsu.edu.cn/anaconda/"},
|
||||
{&Zju, "https://mirrors.zju.edu.cn/anaconda/"},
|
||||
{&Sjtug_Zhiyuan, "https://mirror.sjtu.edu.cn/anaconda"}
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define def_sources_n(t) const size_t t##_sources_n = xy_arylen(t##_sources)
|
||||
|
||||
def_sources_n(pl_ruby); def_sources_n(pl_python); def_sources_n(pl_nodejs);
|
||||
def_sources_n(pl_perl); def_sources_n(pl_php); def_sources_n(pl_lua);
|
||||
def_sources_n(pl_go); def_sources_n(pl_rust);
|
||||
def_sources_n(pl_java); def_sources_n(pl_clojure);
|
||||
def_sources_n(pl_dotnet); def_sources_n(pl_dart); def_sources_n(pl_haskell);
|
||||
def_sources_n(pl_ocaml);
|
||||
def_sources_n(pl_r); def_sources_n(pl_julia);
|
||||
|
||||
def_sources_n(os_ubuntu); def_sources_n(os_mint);
|
||||
def_sources_n(os_debian); def_sources_n(os_fedora);
|
||||
def_sources_n(os_kali); def_sources_n(os_opensuse);
|
||||
def_sources_n(os_arch); def_sources_n(os_msys2); def_sources_n(os_gentoo);
|
||||
def_sources_n(os_alpine); def_sources_n(os_rocky); def_sources_n(os_void);
|
||||
def_sources_n(os_solus);
|
||||
|
||||
def_sources_n(os_trisquel); def_sources_n(os_linuxlite); def_sources_n(os_raspberrypi);
|
||||
|
||||
def_sources_n(os_freebsd); def_sources_n(os_netbsd); def_sources_n(os_openbsd);
|
||||
def_sources_n(os_deepin); def_sources_n(os_openeuler); def_sources_n(os_openkylin);
|
||||
def_sources_n(os_ros);
|
||||
|
||||
def_sources_n(wr_brew); def_sources_n(wr_flathub);
|
||||
def_sources_n(wr_nix); def_sources_n(wr_guix);
|
||||
def_sources_n(wr_tex); def_sources_n(wr_emacs);
|
||||
def_sources_n(wr_anaconda);
|
612
include/xy.h
Normal file
612
include/xy.h
Normal file
@@ -0,0 +1,612 @@
|
||||
/** ------------------------------------------------------------
|
||||
* File : xy.h
|
||||
* License : MIT
|
||||
* Authors : Aoran Zeng <ccmywish@qq.com>
|
||||
* Created on : <2023-08-28>
|
||||
* Last modified : <2024-04-18>
|
||||
*
|
||||
* xy:
|
||||
*
|
||||
* y = f(x)
|
||||
*
|
||||
* Corss-Platform C utilities for CLI applications in Ruby flavor
|
||||
*
|
||||
* 该文件采用 MIT 许可证,请查阅 LICENSE.txt 文件
|
||||
* ------------------------------------------------------------*/
|
||||
|
||||
#ifndef XY_H
|
||||
#define XY_H
|
||||
|
||||
#define XY_Version "v0.1.1-2024/04/18"
|
||||
#define XY_Maintain_URL "https://gitee.com/RubyMetric/chsrc/blob/main/xy.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// #define NDEBUG
|
||||
|
||||
#ifdef _WIN32
|
||||
#define xy_on_windows true
|
||||
#define xy_on_linux false
|
||||
#define xy_on_macos false
|
||||
#define xy_on_bsd false
|
||||
#define xy_os_devnull "nul"
|
||||
#include <windows.h>
|
||||
#define xy_useutf8() SetConsoleOutputCP (65001)
|
||||
|
||||
#elif defined(__linux__) || defined(__linux)
|
||||
#define xy_on_windows false
|
||||
#define xy_on_linux true
|
||||
#define xy_on_macos false
|
||||
#define xy_on_bsd false
|
||||
#define xy_os_devnull "/dev/null"
|
||||
#define xy_useutf8()
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
#define xy_on_windows false
|
||||
#define xy_on_linux false
|
||||
#define xy_on_macos true
|
||||
#define xy_on_bsd false
|
||||
#define xy_os_devnull "/dev/null"
|
||||
#define xy_useutf8()
|
||||
|
||||
#elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__)
|
||||
#define xy_on_windows false
|
||||
#define xy_on_linux false
|
||||
#define xy_on_macos false
|
||||
#define xy_on_bsd true
|
||||
#define xy_os_devnull "/dev/null"
|
||||
#define xy_useutf8()
|
||||
#endif
|
||||
|
||||
void
|
||||
putf (double n)
|
||||
{
|
||||
printf ("%f\n", n);
|
||||
}
|
||||
void
|
||||
puti (long long n)
|
||||
{
|
||||
printf ("%lld\n", n);
|
||||
}
|
||||
void
|
||||
putb (bool n)
|
||||
{
|
||||
if (n)
|
||||
puts ("true");
|
||||
else
|
||||
puts ("false");
|
||||
}
|
||||
void
|
||||
print (char *s)
|
||||
{
|
||||
printf ("%s", s);
|
||||
}
|
||||
void
|
||||
println (char *s)
|
||||
{
|
||||
printf ("%s\n", s);
|
||||
}
|
||||
|
||||
#define xy_arylen(x) (sizeof (x) / sizeof (x[0]))
|
||||
|
||||
#define assert_str(a, b) assert (xy_streql ((a), (b)))
|
||||
|
||||
static inline void *
|
||||
xy_malloc0 (size_t size)
|
||||
{
|
||||
void *ptr = malloc (size);
|
||||
memset (ptr, 0, size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#define XY_Log_Info 00001
|
||||
#define XY_Log_Success 00001 << 1
|
||||
#define XY_Log_Warn 00001 << 2
|
||||
#define XY_Log_Error 00001 << 3
|
||||
|
||||
#define xy_success(str) _xy_log (XY_Log_Success, str)
|
||||
#define xy_info(str) _xy_log (XY_Log_Info, str)
|
||||
#define xy_warn(str) _xy_log (XY_Log_Warn, str)
|
||||
#define xy_error(str) _xy_log (XY_Log_Error, str)
|
||||
|
||||
static void
|
||||
_xy_log (int level, const char *str)
|
||||
{
|
||||
char *color_fmt_str = NULL;
|
||||
|
||||
bool to_stderr = false;
|
||||
|
||||
if (level & XY_Log_Info)
|
||||
{
|
||||
color_fmt_str = "\033[34m%s\033[0m"; // 蓝色
|
||||
}
|
||||
else if (level & XY_Log_Success)
|
||||
{
|
||||
color_fmt_str = "\033[32m%s\033[0m"; // 绿色
|
||||
}
|
||||
else if (level & XY_Log_Warn)
|
||||
{
|
||||
color_fmt_str = "\033[33m%s\033[0m\n"; // 黄色
|
||||
to_stderr = true;
|
||||
}
|
||||
else if (level & XY_Log_Error)
|
||||
{
|
||||
color_fmt_str = "\033[31m%s\033[0m\n"; // 红色
|
||||
to_stderr = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// xy_assert ("CAN'T REACH!");
|
||||
}
|
||||
|
||||
// -2 把中间%s减掉
|
||||
size_t len = strlen (color_fmt_str) - 2;
|
||||
char *buf = malloc (strlen (str) + len + 1);
|
||||
|
||||
sprintf (buf, color_fmt_str, str);
|
||||
if (to_stderr)
|
||||
{
|
||||
fprintf (stderr, "%s", buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
puts (buf);
|
||||
}
|
||||
free (buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将str中所有的pat字符串替换成replace,返回一个全新的字符串
|
||||
*/
|
||||
static char *
|
||||
xy_str_gsub (const char *str, const char *pat, const char *replace)
|
||||
{
|
||||
size_t replace_len = strlen (replace);
|
||||
size_t pat_len = strlen (pat);
|
||||
|
||||
int unit = replace_len - pat_len;
|
||||
if (unit <= 0)
|
||||
unit = 0;
|
||||
|
||||
size_t len = strlen (str);
|
||||
|
||||
const char *cur = str;
|
||||
int count = 0;
|
||||
|
||||
while (cur < str + len)
|
||||
{
|
||||
char *fnd = strstr (cur, pat);
|
||||
if (fnd)
|
||||
{
|
||||
count++;
|
||||
cur = fnd + pat_len;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
// puti(count); DEBUG 匹配次数
|
||||
|
||||
char *ret = malloc (unit * count + len + 1);
|
||||
char *retcur = ret;
|
||||
|
||||
cur = str;
|
||||
while (cur < str + len)
|
||||
{
|
||||
char *fnd = strstr (cur, pat);
|
||||
if (fnd)
|
||||
{
|
||||
ptrdiff_t diff = fnd - cur;
|
||||
strncpy (retcur, cur, diff);
|
||||
cur = fnd + pat_len;
|
||||
|
||||
retcur += diff;
|
||||
strcpy (retcur, replace);
|
||||
retcur += replace_len;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
strcpy (retcur, cur);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char *
|
||||
xy_2strjoin (const char *str1, const char *str2)
|
||||
{
|
||||
size_t len = strlen (str1);
|
||||
size_t size = len + strlen (str2) + 1;
|
||||
char *ret = malloc (size);
|
||||
strcpy (ret, str1);
|
||||
strcpy (ret + len, str2);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char *
|
||||
xy_strjoin (unsigned int count, ...)
|
||||
{
|
||||
size_t al_fixed = 128;
|
||||
char *ret = calloc (1, al_fixed);
|
||||
// 已分配次数
|
||||
int al_times = 1;
|
||||
// 当前已分配量
|
||||
size_t al_cur = al_fixed;
|
||||
|
||||
const char *str = NULL;
|
||||
// 需要分配的量
|
||||
size_t al_need = 0;
|
||||
// 用于 strcpy() 到 ret 的哪个位置
|
||||
char *cur = ret + 0;
|
||||
|
||||
va_list args;
|
||||
va_start (args, count);
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
// 是否需要重新分配
|
||||
bool need_realloc = false;
|
||||
|
||||
str = va_arg (args, const char *);
|
||||
al_need += strlen (str);
|
||||
while (al_need > al_cur)
|
||||
{
|
||||
al_times += 1;
|
||||
al_cur = al_times * al_fixed;
|
||||
need_realloc = true;
|
||||
}
|
||||
// printf("al_times %d, al_need %zd, al_cur %zd\n", al_times, al_need,
|
||||
// al_cur);
|
||||
if (need_realloc)
|
||||
{
|
||||
ptrdiff_t diff = cur - ret;
|
||||
ret = realloc (ret, al_cur);
|
||||
cur = ret + diff;
|
||||
}
|
||||
if (NULL == ret)
|
||||
{
|
||||
xy_error ("xy: No availble memory!");
|
||||
return NULL;
|
||||
}
|
||||
strcpy (cur, str);
|
||||
// puts(ret);
|
||||
cur += strlen (str);
|
||||
}
|
||||
va_end (args);
|
||||
|
||||
*cur = '\0';
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char *
|
||||
xy_strdup (const char *str)
|
||||
{
|
||||
size_t len = strlen (str);
|
||||
char *new = xy_malloc0 (len + 1);
|
||||
strcpy (new, str);
|
||||
return new;
|
||||
}
|
||||
|
||||
#define XY_Str_Bold 1
|
||||
#define XY_Str_Faint 2
|
||||
#define XY_Str_Italic 3
|
||||
#define XY_Str_Underline 4
|
||||
#define XY_Str_Blink 5
|
||||
#define XY_Str_Cross 9
|
||||
|
||||
#define xy_str_to_bold(str) _xy_str_to_terminal_style (XY_Str_Bold, str)
|
||||
#define xy_str_to_faint(str) _xy_str_to_terminal_style (XY_Str_Faint, str)
|
||||
#define xy_str_to_italic(str) _xy_str_to_terminal_style (XY_Str_Italic, str)
|
||||
#define xy_str_to_underline(str) \
|
||||
_xy_str_to_terminal_style (XY_Str_Underline, str)
|
||||
#define xy_str_to_blink(str) _xy_str_to_terminal_style (XY_Str_Blink, str)
|
||||
#define xy_str_to_cross(str) _xy_str_to_terminal_style (XY_Str_Cross, str)
|
||||
|
||||
#define XY_Str_Red 31
|
||||
#define XY_Str_Green 32
|
||||
#define XY_Str_Yellow 33
|
||||
#define XY_Str_Blue 34
|
||||
#define XY_Str_Magenta 35
|
||||
#define XY_Str_Cyan 36
|
||||
|
||||
#define xy_str_to_red(str) _xy_str_to_terminal_style (XY_Str_Red, str)
|
||||
#define xy_str_to_green(str) _xy_str_to_terminal_style (XY_Str_Green, str)
|
||||
#define xy_str_to_yellow(str) _xy_str_to_terminal_style (XY_Str_Yellow, str)
|
||||
#define xy_str_to_blue(str) _xy_str_to_terminal_style (XY_Str_Blue, str)
|
||||
#define xy_str_to_magenta(str) _xy_str_to_terminal_style (XY_Str_Magenta, str)
|
||||
#define xy_str_to_purple xy_str_to_magenta
|
||||
#define xy_str_to_cyan(str) _xy_str_to_terminal_style (XY_Str_Cyan, str)
|
||||
|
||||
static char *
|
||||
_xy_str_to_terminal_style (int style, const char *str)
|
||||
{
|
||||
char *color_fmt_str = NULL;
|
||||
|
||||
switch (style)
|
||||
{
|
||||
case XY_Str_Red:
|
||||
color_fmt_str = "\e[31m%s\e[0m"; break;
|
||||
case XY_Str_Green:
|
||||
color_fmt_str = "\e[32m%s\e[0m"; break;
|
||||
case XY_Str_Yellow:
|
||||
color_fmt_str = "\e[33m%s\e[0m"; break;
|
||||
case XY_Str_Blue:
|
||||
color_fmt_str = "\e[34m%s\e[0m"; break;
|
||||
case XY_Str_Magenta:
|
||||
color_fmt_str = "\e[35m%s\e[0m"; break;
|
||||
case XY_Str_Cyan:
|
||||
color_fmt_str = "\e[36m%s\e[0m"; break;
|
||||
case XY_Str_Bold:
|
||||
color_fmt_str = "\e[1m%s\e[0m"; break;
|
||||
case XY_Str_Faint:
|
||||
color_fmt_str = "\e[2m%s\e[0m"; break;
|
||||
case XY_Str_Italic:
|
||||
color_fmt_str = "\e[3m%s\e[0m"; break;
|
||||
case XY_Str_Underline:
|
||||
color_fmt_str = "\e[4m%s\e[0m"; break;
|
||||
case XY_Str_Blink:
|
||||
color_fmt_str = "\e[5m%s\e[0m"; break;
|
||||
case XY_Str_Cross:
|
||||
color_fmt_str = "\e[9m%s\e[0m"; break;
|
||||
}
|
||||
|
||||
// -2 把中间%s减掉
|
||||
size_t len = strlen (color_fmt_str) - 2;
|
||||
char *buf = malloc (strlen (str) + len + 1);
|
||||
sprintf (buf, color_fmt_str, str);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static bool
|
||||
xy_streql (const char *str1, const char *str2)
|
||||
{
|
||||
return strcmp (str1, str2) == 0 ? true : false;
|
||||
}
|
||||
|
||||
static char *
|
||||
xy_str_to_quietcmd (const char *cmd)
|
||||
{
|
||||
char *ret = NULL;
|
||||
#ifdef _WIN32
|
||||
ret = xy_2strjoin (cmd, " >nul 2>nul ");
|
||||
#else
|
||||
ret = xy_2strjoin (cmd, " 1>/dev/null 2>&1 ");
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool
|
||||
xy_str_end_with (const char *str, const char *suffix)
|
||||
{
|
||||
size_t len1 = strlen (str);
|
||||
size_t len2 = strlen (suffix);
|
||||
|
||||
if (0 == len2)
|
||||
return true; // 空字符串直接返回
|
||||
if (len1 < len2)
|
||||
return false;
|
||||
|
||||
const char *cur1 = str + len1 - 1;
|
||||
const char *cur2 = suffix + len2 - 1;
|
||||
|
||||
for (int i = 0; i < len2; i++)
|
||||
{
|
||||
if (*cur1 != *cur2)
|
||||
return false;
|
||||
cur1--;
|
||||
cur2--;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
xy_str_start_with (const char *str, const char *prefix)
|
||||
{
|
||||
size_t len1 = strlen (str);
|
||||
size_t len2 = strlen (prefix);
|
||||
|
||||
if (0 == len2)
|
||||
return true; // 空字符串直接返回
|
||||
if (len1 < len2)
|
||||
return false;
|
||||
|
||||
const char *cur1 = str;
|
||||
const char *cur2 = prefix;
|
||||
|
||||
for (int i = 0; i < len2; i++)
|
||||
{
|
||||
if (*cur1 != *cur2)
|
||||
return false;
|
||||
cur1++;
|
||||
cur2++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static char *
|
||||
xy_str_delete_prefix (const char *str, const char *prefix)
|
||||
{
|
||||
char *new = xy_strdup (str);
|
||||
bool yes = xy_str_start_with (str, prefix);
|
||||
if (!yes)
|
||||
return new;
|
||||
|
||||
size_t len = strlen (prefix);
|
||||
char *cur = new + len;
|
||||
return cur;
|
||||
}
|
||||
|
||||
static char *
|
||||
xy_str_delete_suffix (const char *str, const char *suffix)
|
||||
{
|
||||
char *new = xy_strdup (str);
|
||||
bool yes = xy_str_end_with (str, suffix);
|
||||
if (!yes)
|
||||
return new;
|
||||
|
||||
size_t len1 = strlen (str);
|
||||
size_t len2 = strlen (suffix);
|
||||
char *cur = new + len1 - len2;
|
||||
*cur = '\0';
|
||||
return new;
|
||||
}
|
||||
|
||||
static char *
|
||||
xy_str_strip (const char *str)
|
||||
{
|
||||
char *new = xy_strdup (str);
|
||||
|
||||
while (strchr ("\n\r\v\t\f ", new[0]))
|
||||
{
|
||||
new += 1;
|
||||
}
|
||||
|
||||
size_t len = strlen (new);
|
||||
|
||||
char *last = new + len - 1;
|
||||
|
||||
while (strchr ("\n\r\v\t\f ", *last))
|
||||
{
|
||||
*last = '\0';
|
||||
last -= 1;
|
||||
}
|
||||
return new;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行cmd,返回其最后某行输出结果
|
||||
*
|
||||
* @param cmd 要执行的命令
|
||||
* @param n 命令打印的结果行,0 表示最后一行,n (n>0) 表示第n行
|
||||
* @param func 对读取的行执行函数
|
||||
*
|
||||
* @note 返回的字符串最后面可能有换行符号
|
||||
*/
|
||||
static char *
|
||||
xy_getcmd (const char *cmd, unsigned long n, void (*func) (const char *))
|
||||
{
|
||||
const int size = 512;
|
||||
char *buf = (char *)malloc (size);
|
||||
|
||||
FILE *stream = popen (cmd, "r");
|
||||
if (stream == NULL)
|
||||
{
|
||||
fprintf (stderr, "xy: 命令执行失败\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *ret = NULL;
|
||||
unsigned long count = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (NULL == fgets (buf, size, stream))
|
||||
break;
|
||||
ret = buf;
|
||||
count += 1;
|
||||
if (n == count)
|
||||
break;
|
||||
if (func)
|
||||
{
|
||||
func (buf);
|
||||
}
|
||||
}
|
||||
|
||||
pclose (stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define xy_os_home _xy_os_home ()
|
||||
static char *
|
||||
_xy_os_home ()
|
||||
{
|
||||
char *home = NULL;
|
||||
if (xy_on_windows)
|
||||
home = getenv ("USERPROFILE");
|
||||
else
|
||||
home = getenv ("HOME");
|
||||
return home;
|
||||
}
|
||||
|
||||
#define xy_win_powershell_profile _xy_win_powershell_profile ()
|
||||
#define xy_win_powershellv5_profile _xy_win_powershellv5_profile ()
|
||||
static char *
|
||||
_xy_win_powershell_profile ()
|
||||
{
|
||||
return xy_2strjoin (
|
||||
xy_os_home, "\\Documents\\PowerShell\\Microsoft.PowerShell_profile.ps1");
|
||||
}
|
||||
|
||||
char *
|
||||
_xy_win_powershellv5_profile ()
|
||||
{
|
||||
return xy_2strjoin (
|
||||
xy_os_home,
|
||||
"\\Documents\\WindowsPowerShell\\Microsoft.PowerShell_profile.ps1");
|
||||
}
|
||||
|
||||
/**
|
||||
* @note Windows上,`path` 不要夹带变量名,因为最终 access() 不会帮你转换
|
||||
*/
|
||||
static bool
|
||||
xy_file_exist (const char *path)
|
||||
{
|
||||
const char *newpath = path;
|
||||
if (xy_on_windows)
|
||||
{
|
||||
if (xy_str_start_with (path, "~"))
|
||||
{
|
||||
newpath = xy_2strjoin (xy_os_home, path + 1);
|
||||
}
|
||||
}
|
||||
return access (newpath, 0) ? false : true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 该函数即使在非Windows下也可调用,作用是删除路径左右两边多出来的空白符
|
||||
*/
|
||||
static char *
|
||||
xy_uniform_path (const char *path)
|
||||
{
|
||||
char *new = xy_str_strip (path); // 防止开发者多写了空白符
|
||||
|
||||
// 这个函数仅在Windows上才进行替换
|
||||
if (xy_on_windows)
|
||||
{
|
||||
if (xy_str_start_with (new, "~/"))
|
||||
{
|
||||
// 或 %USERPROFILE%
|
||||
new = xy_strjoin (3, xy_os_home, "\\",
|
||||
xy_str_delete_prefix (new, "~/"));
|
||||
}
|
||||
new = xy_str_gsub (new, "/", "\\");
|
||||
}
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
static char *
|
||||
xy_parent_dir (const char *path)
|
||||
{
|
||||
char *dir = xy_uniform_path (path);
|
||||
char *last = NULL;
|
||||
if (xy_on_windows)
|
||||
{
|
||||
last = strrchr (dir, '\\');
|
||||
*last = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
last = strrchr (dir, '/');
|
||||
*last = '\0';
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user