From: Daniel Stenberg Date: Mon, 25 Mar 2024 12:07:48 +0000 (+0100) Subject: curl: make --help adapt to the terminal width X-Git-Tag: curl-8_8_0~345 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2efc111ea4cac94baf6e3febd20ad0d855eee3b3;p=thirdparty%2Fcurl.git curl: make --help adapt to the terminal width Instead of assuming and working with 80 colums, try figuring out what width is actually used. Ref: #13141 Closes #13171 --- diff --git a/src/tool_cb_prg.c b/src/tool_cb_prg.c index 86b6fa6055..bf42d7ee2a 100644 --- a/src/tool_cb_prg.c +++ b/src/tool_cb_prg.c @@ -229,28 +229,25 @@ int tool_progress_cb(void *clientp, return 0; } -void progressbarinit(struct ProgressData *bar, - struct OperationConfig *config) -{ - char *colp; - memset(bar, 0, sizeof(struct ProgressData)); - - /* pass the resume from value through to the progress function so it can - * display progress towards total file not just the part that's left. */ - if(config->use_resume) - bar->initial_size = config->resume_from; +/* + * get_terminal_columns() returns the number of columns in the current + * terminal. It will return 79 on failure. Also, the number can be very big. + */ - colp = curlx_getenv("COLUMNS"); +unsigned int get_terminal_columns(void) +{ + unsigned int width = 0; + char *colp = curlx_getenv("COLUMNS"); if(colp) { char *endptr; long num = strtol(colp, &endptr, 10); if((endptr != colp) && (endptr == colp + strlen(colp)) && (num > 20) && (num < 10000)) - bar->width = (int)num; + width = (unsigned int)num; curl_free(colp); } - if(!bar->width) { + if(!width) { int cols = 0; #ifdef TIOCGSIZE @@ -277,14 +274,30 @@ void progressbarinit(struct ProgressData *bar, } } #endif /* TIOCGSIZE */ - if(cols > 20) - bar->width = cols; + if(cols < 10000) + width = cols; } + if(!width) + width = 79; + return width; /* 79 for unknown, might also be very small or very big */ +} + +void progressbarinit(struct ProgressData *bar, + struct OperationConfig *config) +{ + int cols; + memset(bar, 0, sizeof(struct ProgressData)); + + /* pass the resume from value through to the progress function so it can + * display progress towards total file not just the part that's left. */ + if(config->use_resume) + bar->initial_size = config->resume_from; - if(!bar->width) - bar->width = 79; - else if(bar->width > MAX_BARLENGTH) + cols = get_terminal_columns(); + if(cols > MAX_BARLENGTH) bar->width = MAX_BARLENGTH; + else if(cols > 20) + bar->width = cols; bar->out = tool_stderr; bar->tick = 150; diff --git a/src/tool_cb_prg.h b/src/tool_cb_prg.h index 565ad565a9..b012457dfa 100644 --- a/src/tool_cb_prg.h +++ b/src/tool_cb_prg.h @@ -40,9 +40,13 @@ struct ProgressData { int barmove; }; +struct OperationConfig; + void progressbarinit(struct ProgressData *bar, struct OperationConfig *config); +unsigned int get_terminal_columns(void); + /* ** callback for CURLOPT_PROGRESSFUNCTION */ diff --git a/src/tool_help.c b/src/tool_help.c index 26ceea3dd1..fd16af85f3 100644 --- a/src/tool_help.c +++ b/src/tool_help.c @@ -30,6 +30,7 @@ #include "tool_libinfo.h" #include "tool_util.h" #include "tool_version.h" +#include "tool_cb_prg.h" #include "memdebug.h" /* keep this as LAST include */ @@ -73,13 +74,7 @@ static const struct category_descriptors categories[] = { {NULL, NULL, CURLHELP_HIDDEN} }; -#ifdef _WIN32 -#define BORDER 78 -#else -#define BORDER 79 -#endif - -static void print_category(curlhelp_t category) +static void print_category(curlhelp_t category, unsigned int cols) { unsigned int i; size_t longopt = 5; @@ -96,17 +91,16 @@ static void print_category(curlhelp_t category) if(len > longdesc) longdesc = len; } - if(longopt + longdesc >= BORDER) { - longdesc -= 3; - longopt = BORDER -1 - longdesc; - } + if(longopt + longdesc > cols) + longopt = cols - longdesc; + for(i = 0; helptext[i].opt; ++i) if(helptext[i].categories & category) { int opt = (int)longopt; size_t desclen = strlen(helptext[i].desc); - if(opt + desclen >= (BORDER -1)) { - if(desclen < (BORDER -1)) - opt = (BORDER -2) - (int)desclen; + if(opt + desclen >= (cols - 2)) { + if(desclen < (cols - 2)) + opt = (cols - 3) - (int)desclen; else opt = 0; } @@ -115,13 +109,13 @@ static void print_category(curlhelp_t category) } /* Prints category if found. If not, it returns 1 */ -static int get_category_content(const char *category) +static int get_category_content(const char *category, unsigned int cols) { unsigned int i; for(i = 0; categories[i].opt; ++i) if(curl_strequal(categories[i].opt, category)) { printf("%s: %s\n", categories[i].opt, categories[i].desc); - print_category(categories[i].category); + print_category(categories[i].category, cols); return 0; } return 1; @@ -138,6 +132,7 @@ static void get_categories(void) void tool_help(char *category) { + unsigned int cols = get_terminal_columns(); puts("Usage: curl [options...] "); /* If no category was provided */ if(!category) { @@ -145,18 +140,18 @@ void tool_help(char *category) "menu is stripped into categories.\nUse \"--help category\" to get " "an overview of all categories.\nFor all options use the manual" " or \"--help all\"."; - print_category(CURLHELP_IMPORTANT); + print_category(CURLHELP_IMPORTANT, cols); puts(category_note); } /* Lets print everything if "all" was provided */ else if(curl_strequal(category, "all")) /* Print everything except hidden */ - print_category(~(CURLHELP_HIDDEN)); + print_category(~(CURLHELP_HIDDEN), cols); /* Lets handle the string "category" differently to not print an errormsg */ else if(curl_strequal(category, "category")) get_categories(); /* Otherwise print category and handle the case if the cat was not found */ - else if(get_category_content(category)) { + else if(get_category_content(category, cols)) { puts("Invalid category provided, here is a list of all categories:\n"); get_categories(); }