Make the framework compile separately

This commit is contained in:
Aoran Zeng 2025-03-06 20:27:56 +08:00
parent 85f6bfb423
commit c1997265e1
No known key found for this signature in database
GPG Key ID: 8F8BA8488E10ED98
4 changed files with 90 additions and 180 deletions

View File

@ -11,16 +11,12 @@
* Created On : <2023-08-29>
* Last Modified : <2025-03-06>
*
* chsrc framework
* core implementation of chsrc framework
* ------------------------------------------------------------*/
#include "xy.h"
#include "struct.h"
#include "chsrc-framework.h"
#include "mirror.c"
#define App_Name "chsrc"
static int chsrc_get_cpucore ();
bool ProgMode_CMD_Measure = false;
bool ProgMode_CMD_Reset = false;
@ -28,80 +24,21 @@ bool ProgMode_CMD_Reset = false;
bool ProgMode_Target_Group = false;
int ProgMode_Leader_Selected_Index = -1;
/* 此时 chsrc_run() 不再是recipe中指定要运行的一个外部命令而是作为一个功能实现的支撑 */
bool ProgMode_Run_as_a_Service = false;
enum ChgType_t
{
ChgType_Auto,
ChgType_Reset,
ChgType_SemiAuto,
ChgType_Manual,
ChgType_Untested
};
enum ChgType_t ProgMode_ChgType = ChgType_Auto;
/* 命令行选项 */
bool CliOpt_IPv6 = false;
bool CliOpt_Locally = false;
bool CliOpt_InEnglish = false;
bool CliOpt_DryRun = false;
bool CliOpt_NoColor = false;
/**
* -local **
*
* target [-local] 使 | chsrc ls <target> |
*
*
* 1. 使 **
*
* (1) (2)
*
* ** chsrc 使 **
*
* 2. ** chsrc **
*
* 3. poetry
*/
#define Exit_OK 0
#define Exit_Fatal 1
#define Exit_Unknown 2
#define Exit_Unsupported 3
#define Exit_UserCause 4
#define Exit_MaintainerCause 5
#define Exit_ExternalError 6
#define chsrc_log(str) xy_log(App_Name,str)
#define chsrc_succ(str) xy_succ(App_Name,str)
#define chsrc_info(str) xy_info(App_Name,str)
#define chsrc_warn(str) xy_warn(App_Name,str)
#define chsrc_error(str) xy_error(App_Name,str)
#define chsrc_debug(str) xy_warn(App_Name "(DEBUG)",str)
#define chsrc_verbose(str) xy_info(App_Name "(VERBOSE)",str)
#define red(str) xy_str_to_red(str)
#define blue(str) xy_str_to_blue(str)
#define green(str) xy_str_to_green(str)
#define yellow(str) xy_str_to_yellow(str)
#define purple(str) xy_str_to_purple(str)
#define bold(str) xy_str_to_bold(str)
#define bdred(str) xy_str_to_bold(xy_str_to_red(str))
#define bdblue(str) xy_str_to_bold(xy_str_to_blue(str))
#define bdgreen(str) xy_str_to_bold(xy_str_to_green(str))
#define bdyellow(str) xy_str_to_bold(xy_str_to_yellow(str))
#define bdpurple(str) xy_str_to_bold(xy_str_to_purple(str))
// 2系列都是带有括号的
#define chsrc_succ2(str) xy_succ_brkt(App_Name,CliOpt_InEnglish?"SUCCEED":"成功",str)
#define chsrc_log2(str) xy_info_brkt(App_Name,"LOG",str)
#define chsrc_warn2(str) xy_warn_brkt(App_Name,CliOpt_InEnglish?"WARN":"警告",str)
#define chsrc_error2(str) xy_error_brkt(App_Name,CliOpt_InEnglish?"ERROR":"错误",str)
#define chsrc_debug2(str) xy_warn_brkt(App_Name,"DEBUG",str)
#define chsrc_verbose2(str) xy_info_brkt(App_Name,"VERBOSE",str)
void
chsrc_note2 (const char *str)
@ -110,16 +47,16 @@ chsrc_note2 (const char *str)
xy_log_brkt (yellow(App_Name), bdyellow(msg), yellow(str));
}
void
chsrc_log_write (const char *filename)
static void
log_write_op (const char *filename)
{
char *msg = CliOpt_InEnglish ? "WRITE" : "写入";
xy_log_brkt (blue(App_Name), bdblue(msg), blue(filename));
}
void
chsrc_log_backup (const char *filename)
static void
log_backup_op (const char *filename)
{
char *msg = CliOpt_InEnglish ? "BACKUP" : "备份";
@ -131,10 +68,8 @@ chsrc_log_backup (const char *filename)
#define NoMark "x"
#define HalfYesMark "⍻"
/**
* @translation Done
*/
void
static void
log_check_result (const char *check_what, const char *check_type, bool exist)
{
char *chk_msg = NULL;
@ -168,10 +103,7 @@ log_check_result (const char *check_what, const char *check_type, bool exist)
}
/**
* @translation Done
*/
void
static void
log_cmd_result (bool result, int exit_status)
{
char *run_msg = NULL;
@ -220,16 +152,14 @@ is_url (const char *str)
/**
*
*
* @param prog_name
*
* @param check_cmd `prog_name` `prog_name`
* 使 python Windows上
* Microsoft Store
*
* @param prog_name
*
* @translation Done
*/
bool
query_program_exist (char *check_cmd, char *prog_name, int mode)
chsrc_query_program_exist (char *prog_name, char *check_cmd, int mode)
{
char *which = check_cmd;
@ -267,7 +197,7 @@ bool
chsrc_check_program (char *prog_name)
{
char *quiet_cmd = xy_str_to_quietcmd (xy_2strjoin (prog_name, " --version"));
return query_program_exist (quiet_cmd, prog_name, Noisy_When_Exist|Noisy_When_NonExist);
return chsrc_query_program_exist (prog_name, quiet_cmd, Noisy_When_Exist|Noisy_When_NonExist);
}
/**
@ -281,7 +211,7 @@ bool
chsrc_check_program_quietly (char *prog_name)
{
char *quiet_cmd = xy_str_to_quietcmd (xy_2strjoin (prog_name, " --version"));
return query_program_exist (quiet_cmd, prog_name, Quiet_When_Exist|Quiet_When_NonExist);
return chsrc_query_program_exist (prog_name, quiet_cmd, Quiet_When_Exist|Quiet_When_NonExist);
}
/**
@ -292,7 +222,7 @@ bool
chsrc_check_program_quietly_when_exist (char *prog_name)
{
char *quiet_cmd = xy_str_to_quietcmd (xy_2strjoin (prog_name, " --version"));
return query_program_exist (quiet_cmd, prog_name, Quiet_When_Exist|Noisy_When_NonExist);
return chsrc_query_program_exist (prog_name, quiet_cmd, Quiet_When_Exist|Noisy_When_NonExist);
}
@ -306,7 +236,7 @@ void
chsrc_ensure_program (char *prog_name)
{
char *quiet_cmd = xy_str_to_quietcmd (xy_2strjoin (prog_name, " --version"));
bool exist = query_program_exist (quiet_cmd, prog_name, Quiet_When_Exist|Noisy_When_NonExist);
bool exist = chsrc_query_program_exist (prog_name, quiet_cmd, Quiet_When_Exist|Noisy_When_NonExist);
if (exist)
{
// OK, nothing should be done
@ -346,7 +276,6 @@ chsrc_check_file (char *path)
* @param target
* @param input default def
*/
#define find_mirror(s, input) query_provider_exist(s##_sources, s##_sources_n, (char*)#s+3, input)
int
query_provider_exist (Source_t *sources, size_t size, char *target, char *input)
{
@ -433,7 +362,7 @@ query_provider_exist (Source_t *sources, size_t size, char *target, char *input)
*
* @param speed Byte/s
*/
char *
static char *
to_human_readable_speed (double speed)
{
char *scale[] = {"Byte/s", "KByte/s", "MByte/s", "GByte/s", "TByte/s"};
@ -465,7 +394,7 @@ to_human_readable_speed (double speed)
*
* char * (*)(const char*)
*/
void *
static void *
measure_speed_for_url (void *url)
{
char *time_sec = NULL;
@ -510,7 +439,7 @@ measure_speed_for_url (void *url)
/**
* @return speed Byte/s
*/
double
static double
parse_and_say_curl_result (char *curl_buf)
{
// 分隔两部分数据
@ -535,7 +464,7 @@ parse_and_say_curl_result (char *curl_buf)
}
int
static int
get_max_ele_idx_in_dbl_ary (double *array, int size)
{
double maxval = array[0];
@ -558,7 +487,7 @@ get_max_ele_idx_in_dbl_ary (double *array, int size)
* @param size
* @param[out] speed_records Byte/s
*/
void
static void
measure_speed_for_every_source (Source_t sources[], int size, double speed_records[])
{
// bool get_measured[size]; /* 是否真正执行了测速 */
@ -655,7 +584,6 @@ measure_speed_for_every_source (Source_t sources[], int size, double speed_recor
/**
*
*/
#define auto_select_mirror(s) select_mirror_autoly(s##_sources, s##_sources_n, (char*)#s+3)
int
select_mirror_autoly (Source_t *sources, size_t size, const char *target_name)
{
@ -760,73 +688,33 @@ select_mirror_autoly (Source_t *sources, size_t size, const char *target_name)
}
#define use_specific_mirror_or_auto_select(input, s) \
(NULL!=(input)) ? find_mirror(s, input) : auto_select_mirror(s)
bool
static bool
source_is_upstream (Source_t *source)
{
return xy_streql (source->mirror->code, "upstream");
}
bool
static bool
source_is_userdefine (Source_t *source)
{
return xy_streql (source->mirror->code, "user");
}
bool
static bool
source_has_empty_url (Source_t *source)
{
return source->url == NULL;
}
bool
static bool
is_reset_mode ()
{
return ProgMode_CMD_Reset;
}
/**
* **5 Source_t
* option:
* 1. Mirror Code
* 2. NULL: ()
* 3. URL
* 4. ChgType_Reset
* Leader target
* 5. ProgMode_Leader_Selected_Index
*
* @dependency option
*/
#define chsrc_yield_for_the_source(for_what) \
if (ProgMode_Target_Group==true && ProgMode_Leader_Selected_Index==-1) \
{ \
ProgMode_Leader_Selected_Index = use_specific_mirror_or_auto_select (option, for_what); \
source = for_what##_sources[ProgMode_Leader_Selected_Index]; \
} \
else if (ProgMode_Target_Group==true && ProgMode_Leader_Selected_Index!=-1) \
{ \
source = for_what##_sources[ProgMode_Leader_Selected_Index]; \
} \
else if (is_url (option)) \
{ \
Source_t __tmp = { &UserDefinedProvider, option }; \
source = __tmp; \
} \
else \
{ \
int __index = use_specific_mirror_or_auto_select (option, for_what); \
source = for_what##_sources[__index]; \
}
#define chsrc_yield_source(for_what) \
Source_t source; \
chsrc_yield_for_the_source(for_what)
#define hr() say ("--------------------------------");
@ -838,11 +726,9 @@ is_reset_mode ()
* 1.
* 2.
*
* @translation Done
*/
#define chsrc_confirm_source confirm_source(&source)
void
confirm_source (Source_t *source)
chsrc_confirm_source (Source_t *source)
{
// 由于实现问题,我们把本应该独立出去的上游默认源,也放在了可以换源的数组中,而且放在第一个
// chsrc 已经规避用户使用未实现的 `chsrc reset`
@ -870,7 +756,6 @@ confirm_source (Source_t *source)
hr();
}
#define chsrc_yield_source_and_confirm(for_what) chsrc_yield_source(for_what);chsrc_confirm_source
void
@ -1055,12 +940,9 @@ not_root:
}
#define RunOpt_Default 0x0000 // 默认若命令运行失败,直接退出
#define RunOpt_Dont_Notify_On_Success 0x0010 // 运行成功不提示用户,只有运行失败时才提示用户
#define RunOpt_No_Last_New_Line 0x0100 // 不输出最后的空行
#define RunOpt_Dont_Abort_On_Failure 0x1000 // 命令运行失败也不退出
static void
void
chsrc_run (const char *cmd, int run_option)
{
if (ProgMode_Run_as_a_Service)
@ -1107,7 +989,7 @@ chsrc_run (const char *cmd, int run_option)
static void
chsrc_run_as_a_service (const char *cmd)
_chsrc_run_as_a_service (const char *cmd)
{
int run_option = RunOpt_Default;
ProgMode_Run_as_a_Service = true;
@ -1116,7 +998,7 @@ chsrc_run_as_a_service (const char *cmd)
ProgMode_Run_as_a_Service = false;
}
static void
void
chsrc_view_file (const char *path)
{
char *cmd = NULL;
@ -1130,10 +1012,10 @@ chsrc_view_file (const char *path)
cmd = xy_2strjoin ("cat ", path);
}
chsrc_run_as_a_service (cmd);
_chsrc_run_as_a_service (cmd);
}
static void
void
chsrc_ensure_dir (const char *dir)
{
dir = xy_normalize_path (dir);
@ -1156,14 +1038,14 @@ chsrc_ensure_dir (const char *dir)
char *cmd = xy_2strjoin (mkdir_cmd, dir);
cmd = xy_str_to_quietcmd (cmd);
chsrc_run_as_a_service (cmd);
_chsrc_run_as_a_service (cmd);
char *msg = CliOpt_InEnglish ? "Directory doesn't exist, created automatically " : "目录不存在,已自动创建 ";
chsrc_note2 (xy_2strjoin (msg, dir));
}
static void
void
chsrc_append_to_file (const char *str, const char *filename)
{
if (CliOpt_DryRun)
@ -1199,7 +1081,7 @@ chsrc_append_to_file (const char *str, const char *filename)
log_anyway:
/* 输出recipe指定的文件名 */
chsrc_log_write (filename);
log_write_op (filename);
/*
char *cmd = NULL;
@ -1215,7 +1097,7 @@ log_anyway:
*/
}
static void
void
chsrc_prepend_to_file (const char *str, const char *filename)
{
if (CliOpt_DryRun)
@ -1236,14 +1118,14 @@ chsrc_prepend_to_file (const char *str, const char *filename)
{
cmd = xy_strjoin (4, "sed -i '1i ", str, "' ", file);
}
chsrc_run_as_a_service (cmd);
_chsrc_run_as_a_service (cmd);
log_anyway:
/* 输出recipe指定的文件名 */
chsrc_log_write (filename);
log_write_op (filename);
}
static void
void
chsrc_overwrite_file (const char *str, const char *filename)
{
if (CliOpt_DryRun)
@ -1264,14 +1146,14 @@ chsrc_overwrite_file (const char *str, const char *filename)
{
cmd = xy_strjoin (4, "echo '", str, "' > ", file);
}
chsrc_run_as_a_service (cmd);
_chsrc_run_as_a_service (cmd);
log_anyway:
/* 输出recipe指定的文件名 */
chsrc_log_write (filename);
log_write_op (filename);
}
static void
void
chsrc_backup (const char *path)
{
if (CliOpt_DryRun)
@ -1324,17 +1206,17 @@ chsrc_backup (const char *path)
}
}
chsrc_run_as_a_service (cmd);
_chsrc_run_as_a_service (cmd);
log_anyway:
chsrc_log_backup (path);
log_backup_op (path);
}
/**
*
*/
static char *
char *
chsrc_get_cpuarch ()
{
char *ret;
@ -1388,7 +1270,7 @@ chsrc_get_cpuarch ()
}
static int
int
chsrc_get_cpucore ()
{
int cores = 2;

View File

@ -7,9 +7,11 @@
* Contributors : Shengwei Chen <414685209@qq.com>
* |
* Created On : <2023-08-29>
* Last Modified : <2025-03-04>
* Last Modified : <2025-03-06>
*
*
*
* core.c
* ------------------------------------------------------------*/
#define Big_File_ubuntu "/24.04/ubuntu-24.04.1-desktop-amd64.iso" // 5.8 GB
@ -17,6 +19,22 @@
#define Big_File_archlinux "/iso/latest/archlinux-x86_64.iso" // 800 MB
#define Big_File_deepin "/20.9/deepin-desktop-community-20.9-amd64.iso" // 4 GB
SourceProvider_t UserDefinedProvider =
{
"user", "用户自定义", "用户自定义", NULL,
{SKIP, "用户自定义源不测速", "SKIP for user-defined source", NULL}
};
SourceProvider_t UpstreamProvider =
{
/* 引入新的上游默认源时,请使下面第一行的前三个字段保持不变,只添加第四个字段,可使用 def_upstream 宏 */
"upstream", "Upstream", "上游默认源", NULL,
/* 引入新的上游默认源时,请完全修改下面这个结构体,可使用 def_need_measure_info 宏 */
{SKIP, "URL未知邀您参与贡献!", "URL unknown, welcome to contribute!", NULL}
};
/**
*
*
@ -110,7 +128,7 @@ Scau =
{NotSkip, NA, NA, "https://mirrors.scau.edu.cn/ubuntu-releases" Big_File_ubuntu}
},
NJTech =
Njtech =
{
"njtech", "NJTech", "南京工业大学开源软件镜像站", "https://mirrors.njtech.edu.cn/",
{NotSkip, NA, NA, "https://mirrors.njtech.edu.cn/ubuntu-releases" Big_File_ubuntu}

22
src/framework/mirror.h Normal file
View File

@ -0,0 +1,22 @@
/** ------------------------------------------------------------
* SPDX-License-Identifier: GPL-3.0-or-later
* -------------------------------------------------------------
* File Name : mirror.h
* File Authors : Aoran Zeng <ccmywish@qq.com>
* | Heng Guo <2085471348@qq.com>
* Contributors : Shengwei Chen <414685209@qq.com>
* |
* Created On : <2023-08-29>
* Last Modified : <2025-03-06>
*
* chsrc-framework.h
* ------------------------------------------------------------*/
extern SourceProvider_t UpstreamProvider;
extern SourceProvider_t UserDefinedProvider;
extern MirrorSite_t MirrorZ,
Tuna, Sjtug_Zhiyuan, Zju, Lzuoss, Jlu, Bfsu, Pku, Bjtu,
Sustech, Ustc, Hust, Iscas, Scau, Njtech, Nyist, Sdu, Cqupt, Nju;
extern MirrorSite_t Ali, Tencent, Huawei, Volcengine, Netease, Sohu;

View File

@ -7,7 +7,7 @@
* Contributors : Shengwei Chen <414685209@qq.com>
* |
* Created On : <2023-08-29>
* Last Modified : <2024-12-18>
* Last Modified : <2025-03-06>
*
* chsrc struct
* ------------------------------------------------------------*/
@ -38,22 +38,10 @@ SourceProvider_t;
typedef SourceProvider_t MirrorSite_t;
SourceProvider_t UpstreamProvider =
{
/* 引入新的上游默认源时,请使下面第一行的前三个字段保持不变,只添加第四个字段,可使用 def_upstream 宏 */
"upstream", "Upstream", "上游默认源", NULL,
/* 引入新的上游默认源时,请完全修改下面这个结构体,可使用 def_need_measure_info 宏 */
{SKIP, "URL未知邀您参与贡献!", "URL unknown, welcome to contribute!", NULL}
};
#define def_upstream "upstream", "Upstream", "上游默认源"
#define def_need_measure_info {SKIP, "缺乏较大的测速对象,邀您参与贡献!", "Lack of large object URL, welcome to contribute!", NULL}
SourceProvider_t UserDefinedProvider =
{
"user", "用户自定义", "用户自定义", NULL,
{SKIP, "用户自定义源不测速", "SKIP for user-defined source", NULL}
};
typedef struct Source_t