patch 9.1.1365: MS-Windows: compile warnings and too many strlen() calls Commit: https://github.com/vim/vim/commit/51f6a78ce250f133b29b0e5aabafa9826fd15e4f Author: John Marriott <basil...@internode.on.net> Date: Sun May 4 21:35:36 2025 +0200
patch 9.1.1365: MS-Windows: compile warnings and too many strlen() calls Problem: MS-Windows: compile warnings and too many strlen() calls in os_mswin.c Solution: refactor os_mswin.c and fix the warning (John Marriott) This change does the following: - Fix compile warnings (clang 20.1.3) in `mch_libcall()`: ``` os_mswin.c:902:21: warning: cast from 'MYSTRPROCSTR' (aka 'char *(*)(char *)') to 'MYSTRPROCINT' (aka 'int (*)(char *)') converts to incompatible function type [-Wcast-function-type-mismatch]` 902 | retval_int = ((MYSTRPROCINT)ProcAdd)((LPSTR)argstring);` | ^~~~~~~~~~~~~~~~~~~~~` os_mswin.c:914:21: warning: cast from 'MYINTPROCSTR' (aka 'char *(*)(int)') to 'MYINTPROCINT' (aka 'int (*)(int)') converts to incompatible function type [-Wcast-function-type-mismatch]` 914 | retval_int = ((MYINTPROCINT)ProcAddI)(argint);` | ^~~~~~~~~~~~~~~~~~~~~~` 2 warnings generated. ``` - Refactor `stat_impl()` to remove call to `STRLEN()` (via `STRCAT()`). - Refactor `Messaging_WndProc()`, `enumWindowsGetServer()` and `serverSendToVim()` to remove calls to `STRLEN()`. - Use `string_T` to store field `name` in `struct charset_pair` and `struct quality_pair`. This means we can dispense with some calls to `STRLEN()`. - Use `ARRAY_LENGTH()` macro to determine end of array in `charset_id2name()` and `quality_id2name()` to be consistent with the rest of the code base. closes: #17222 Signed-off-by: John Marriott <basil...@internode.on.net> Signed-off-by: Christian Brabandt <c...@256bit.org> diff --git a/src/os_mswin.c b/src/os_mswin.c index 4d09f9ecd..7a323f327 100644 --- a/src/os_mswin.c +++ b/src/os_mswin.c @@ -513,18 +513,23 @@ stat_impl(const char *name, stat_T *stp, const int resolve) // means that the maximum pathname is _MAX_PATH * 3 bytes when 'enc' is // UTF-8. char_u buf[_MAX_PATH * 3 + 1]; + size_t buflen; char_u *p; WCHAR *wp; int n; vim_strncpy((char_u *)buf, (char_u *)name, sizeof(buf) - 1); - p = buf + STRLEN(buf); + buflen = STRLEN(buf); + p = buf + buflen; if (p > buf) MB_PTR_BACK(buf, p); // Remove trailing '\' except root path. if (p > buf && (*p == '\' || *p == '/') && p[-1] != ':') + { *p = NUL; + buflen = (size_t)(p - buf); + } if ((buf[0] == '\' && buf[1] == '\') || (buf[0] == '/' && buf[1] == '/')) { @@ -534,7 +539,7 @@ stat_impl(const char *name, stat_T *stp, const int resolve) { p = vim_strpbrk(p + 1, (char_u *)"\/"); if (p == NULL) - STRCAT(buf, "\"); + STRCPY(buf + buflen, "\"); } } @@ -759,9 +764,9 @@ mch_check_messages(void) * and returns an allocated string. * Return OK if it worked, FAIL if not. */ -typedef LPTSTR (*MYSTRPROCSTR)(LPTSTR); -typedef LPTSTR (*MYINTPROCSTR)(int); -typedef int (*MYSTRPROCINT)(LPTSTR); +typedef char_u *(*MYSTRPROCSTR)(char_u *); +typedef int (*MYSTRPROCINT)(char_u *); +typedef char_u *(*MYINTPROCSTR)(int); typedef int (*MYINTPROCINT)(int); /* @@ -874,11 +879,6 @@ mch_libcall( int *number_result) { HINSTANCE hinstLib; - MYSTRPROCSTR ProcAdd; - MYINTPROCSTR ProcAddI; - char_u *retval_str = NULL; - int retval_int = 0; - size_t len; BOOL fRunTimeLinkSuccess = FALSE; @@ -888,6 +888,10 @@ mch_libcall( // If the handle is valid, try to get the function address. if (hinstLib != NULL) { + char_u *retval_str = NULL; + int retval_int = 0; + size_t len; + # ifdef HAVE_TRY_EXCEPT __try { @@ -895,25 +899,53 @@ mch_libcall( if (argstring != NULL) { // Call with string argument - ProcAdd = (MYSTRPROCSTR)GetProcAddress(hinstLib, (LPCSTR)funcname); - if ((fRunTimeLinkSuccess = (ProcAdd != NULL)) != 0) + if (string_result != NULL) { - if (string_result == NULL) - retval_int = ((MYSTRPROCINT)ProcAdd)((LPSTR)argstring); - else - retval_str = (char_u *)(ProcAdd)((LPSTR)argstring); + MYSTRPROCSTR proc; + + proc = (MYSTRPROCSTR)GetProcAddress(hinstLib, (LPCSTR)funcname); + if (proc != NULL) + { + fRunTimeLinkSuccess = TRUE; + retval_str = proc(argstring); + } + } + else + { + MYSTRPROCINT proc; + + proc = (MYSTRPROCINT)GetProcAddress(hinstLib, (LPCSTR)funcname); + if (proc != NULL) + { + fRunTimeLinkSuccess = TRUE; + retval_int = proc(argstring); + } } } else { // Call with number argument - ProcAddI = (MYINTPROCSTR) GetProcAddress(hinstLib, (LPCSTR)funcname); - if ((fRunTimeLinkSuccess = (ProcAddI != NULL)) != 0) + if (string_result != NULL) { - if (string_result == NULL) - retval_int = ((MYINTPROCINT)ProcAddI)(argint); - else - retval_str = (char_u *)(ProcAddI)(argint); + MYINTPROCSTR proc; + + proc = (MYINTPROCSTR)GetProcAddress(hinstLib, (LPCSTR)funcname); + if (proc != NULL) + { + fRunTimeLinkSuccess = TRUE; + retval_str = proc(argint); + } + } + else + { + MYINTPROCINT proc; + + proc = (MYINTPROCINT)GetProcAddress(hinstLib, (LPCSTR)funcname); + if (proc != NULL) + { + fRunTimeLinkSuccess = TRUE; + retval_int = proc(argint); + } } } @@ -935,7 +967,7 @@ mch_libcall( { if (GetExceptionCode() == EXCEPTION_STACK_OVERFLOW) _resetstkoflw(); - fRunTimeLinkSuccess = 0; + fRunTimeLinkSuccess = FALSE; } # endif @@ -2077,13 +2109,18 @@ Messaging_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) res = alloc(len); if (res != NULL) - vim_snprintf((char *)res, len, "%s: \"%s\"", err, str); + reply.cbData = (DWORD)vim_snprintf_safelen( + (char *)res, len, "%s: \"%s\"", err, str); + else + reply.cbData = 0; reply.dwData = COPYDATA_ERROR_RESULT; } else + { + reply.cbData = (DWORD)STRLEN(res) + 1; reply.dwData = COPYDATA_RESULT; + } reply.lpData = res; - reply.cbData = (DWORD)STRLEN(res) + 1; if (serverSendEnc(sender) < 0) retval = -1; @@ -2226,12 +2263,16 @@ enumWindowsGetServer(HWND hwnd, LPARAM lparam) } // If we are looking for an alternate server, remember this name. - if (altname_buf_ptr != NULL - && STRNICMP(server, id->name, STRLEN(id->name)) == 0 - && vim_isdigit(server[STRLEN(id->name)])) + if (altname_buf_ptr != NULL) { - STRCPY(altname_buf_ptr, server); - altname_buf_ptr = NULL; // don't use another name + size_t namelen = STRLEN(id->name); + + if (STRNICMP(server, id->name, namelen) == 0 + && vim_isdigit(server[namelen])) + { + STRCPY(altname_buf_ptr, server); + altname_buf_ptr = NULL; // don't use another name + } } // Otherwise, keep looking @@ -2413,6 +2454,7 @@ serverSendToVim( int timeout, // timeout in seconds or zero int silent) // don't complain about no server { + size_t namelen; HWND target; COPYDATASTRUCT data; char_u *retval = NULL; @@ -2426,7 +2468,8 @@ serverSendToVim( // If the server name does not end in a digit then we look for an // alternate name. e.g. when "name" is GVIM then we may find GVIM2. - if (STRLEN(name) > 1 && !vim_isdigit(name[STRLEN(name) - 1])) + namelen = STRLEN(name); + if (namelen > 1 && !vim_isdigit(name[namelen - 1])) altname_buf_ptr = altname_buf; altname_buf[0] = NUL; target = findServer(name); @@ -2644,63 +2687,65 @@ serverProcessPendingMessages(void) struct charset_pair { - char *name; + string_T name; BYTE charset; }; +#define STRING_INIT(s) \ + {(char_u *)(s), STRLEN_LITERAL(s)} static struct charset_pair charset_pairs[] = { - {"ANSI", ANSI_CHARSET}, - {"CHINESEBIG5", CHINESEBIG5_CHARSET}, - {"DEFAULT", DEFAULT_CHARSET}, - {"HANGEUL", HANGEUL_CHARSET}, - {"OEM", OEM_CHARSET}, - {"SHIFTJIS", SHIFTJIS_CHARSET}, - {"SYMBOL", SYMBOL_CHARSET}, - {"ARABIC", ARABIC_CHARSET}, - {"BALTIC", BALTIC_CHARSET}, - {"EASTEUROPE", EASTEUROPE_CHARSET}, - {"GB2312", GB2312_CHARSET}, - {"GREEK", GREEK_CHARSET}, - {"HEBREW", HEBREW_CHARSET}, - {"JOHAB", JOHAB_CHARSET}, - {"MAC", MAC_CHARSET}, - {"RUSSIAN", RUSSIAN_CHARSET}, - {"THAI", THAI_CHARSET}, - {"TURKISH", TURKISH_CHARSET}, + {STRING_INIT("ANSI"), ANSI_CHARSET}, + {STRING_INIT("CHINESEBIG5"), CHINESEBIG5_CHARSET}, + {STRING_INIT("DEFAULT"), DEFAULT_CHARSET}, + {STRING_INIT("HANGEUL"), HANGEUL_CHARSET}, + {STRING_INIT("OEM"), OEM_CHARSET}, + {STRING_INIT("SHIFTJIS"), SHIFTJIS_CHARSET}, + {STRING_INIT("SYMBOL"), SYMBOL_CHARSET}, + {STRING_INIT("ARABIC"), ARABIC_CHARSET}, + {STRING_INIT("BALTIC"), BALTIC_CHARSET}, + {STRING_INIT("EASTEUROPE"), EASTEUROPE_CHARSET}, + {STRING_INIT("GB2312"), GB2312_CHARSET}, + {STRING_INIT("GREEK"), GREEK_CHARSET}, + {STRING_INIT("HEBREW"), HEBREW_CHARSET}, + {STRING_INIT("JOHAB"), JOHAB_CHARSET}, + {STRING_INIT("MAC"), MAC_CHARSET}, + {STRING_INIT("RUSSIAN"), RUSSIAN_CHARSET}, + {STRING_INIT("THAI"), THAI_CHARSET}, + {STRING_INIT("TURKISH"), TURKISH_CHARSET} # ifdef VIETNAMESE_CHARSET - {"VIETNAMESE", VIETNAMESE_CHARSET}, + , + {STRING_INIT("VIETNAMESE"), VIETNAMESE_CHARSET} # endif - {NULL, 0} }; struct quality_pair { - char *name; + string_T name; DWORD quality; }; static struct quality_pair quality_pairs[] = { # ifdef CLEARTYPE_QUALITY - {"CLEARTYPE", CLEARTYPE_QUALITY}, + {STRING_INIT("CLEARTYPE"), CLEARTYPE_QUALITY}, # endif # ifdef ANTIALIASED_QUALITY - {"ANTIALIASED", ANTIALIASED_QUALITY}, + {STRING_INIT("ANTIALIASED"), ANTIALIASED_QUALITY}, # endif # ifdef NONANTIALIASED_QUALITY - {"NONANTIALIASED", NONANTIALIASED_QUALITY}, + {STRING_INIT("NONANTIALIASED"), NONANTIALIASED_QUALITY}, # endif # ifdef PROOF_QUALITY - {"PROOF", PROOF_QUALITY}, + {STRING_INIT("PROOF"), PROOF_QUALITY}, # endif # ifdef DRAFT_QUALITY - {"DRAFT", DRAFT_QUALITY}, + {STRING_INIT("DRAFT"), DRAFT_QUALITY}, # endif - {"DEFAULT", DEFAULT_QUALITY}, - {NULL, 0} + {STRING_INIT("DEFAULT"), DEFAULT_QUALITY} }; +#undef STRING_INIT /* * Convert a charset ID to a name. @@ -2709,12 +2754,15 @@ quality_pairs[] = { char * charset_id2name(int id) { - struct charset_pair *cp; + int i; - for (cp = charset_pairs; cp->name != NULL; ++cp) - if ((BYTE)id == cp->charset) - break; - return cp->name; + for (i = 0; i < (int)ARRAY_LENGTH(charset_pairs); ++i) + { + if ((BYTE)id == charset_pairs[i].charset) + return (char *)charset_pairs[i].name.string; + } + + return NULL; } /* @@ -2724,12 +2772,15 @@ charset_id2name(int id) char * quality_id2name(DWORD id) { - struct quality_pair *qp; + int i; - for (qp = quality_pairs; qp->name != NULL; ++qp) - if (id == qp->quality) - break; - return qp->name; + for (i = 0; i < (int)ARRAY_LENGTH(quality_pairs); ++i) + { + if (id == quality_pairs[i].quality) + return (char *)quality_pairs[i].name.string; + } + + return NULL; } // The default font height in 100% scaling (96dpi). @@ -2956,6 +3007,7 @@ gui_mch_expand_font(optexpand_T *args, void *param UNUSED, int (*add_match)(char if (xp->xp_pattern > args->oe_set_arg && *(xp->xp_pattern-1) == ':') { char buf[30]; + int i; // Always fill in with the current font size as first option for // convenience. We simply round to the closest integer for simplicity. @@ -2968,19 +3020,18 @@ gui_mch_expand_font(optexpand_T *args, void *param UNUSED, int (*add_match)(char // 'q' as we fill in all the values below. static char *(p_gfn_win_opt_values[]) = { "h" , "w" , "W" , "b" , "i" , "u" , "s"}; - for (size_t i = 0; i < ARRAY_LENGTH(p_gfn_win_opt_values); i++) + for (i = 0; i < (int)ARRAY_LENGTH(p_gfn_win_opt_values); i++) add_match((char_u *)p_gfn_win_opt_values[i]); - struct charset_pair *cp; - for (cp = charset_pairs; cp->name != NULL; ++cp) + for (i = 0; i < (int)ARRAY_LENGTH(charset_pairs); ++i) { - vim_snprintf(buf, ARRAY_LENGTH(buf), "c%s", cp->name); + vim_snprintf(buf, sizeof(buf), "c%s", charset_pairs[i].name.string); add_match((char_u *)buf); } - struct quality_pair *qp; - for (qp = quality_pairs; qp->name != NULL; ++qp) + + for (i = 0; i < (int)ARRAY_LENGTH(quality_pairs); ++i) { - vim_snprintf(buf, ARRAY_LENGTH(buf), "q%s", qp->name); + vim_snprintf(buf, sizeof(buf), "q%s", quality_pairs[i].name.string); add_match((char_u *)buf); } return; @@ -3039,7 +3090,7 @@ set_default_logfont(LOGFONTW *lf) const char *defaultfontname = N_("DefaultFontNameForWindows"); char *fontname = _(defaultfontname); - if (strcmp(fontname, defaultfontname) == 0) + if (STRCMP(fontname, defaultfontname) == 0) fontname = "Consolas"; *lf = s_lfDefault; @@ -3167,53 +3218,51 @@ get_logfont( lf->lfStrikeOut = TRUE; break; case L'c': + for (i = 0; i < (int)ARRAY_LENGTH(charset_pairs); ++i) { - struct charset_pair *cp; - - for (cp = charset_pairs; cp->name != NULL; ++cp) - if (utf16ascncmp(p, cp->name, strlen(cp->name)) == 0) - { - lf->lfCharSet = cp->charset; - p += strlen(cp->name); - break; - } - if (cp->name == NULL && verbose) + if (utf16ascncmp(p, (char *)charset_pairs[i].name.string, + charset_pairs[i].name.length) == 0) { - char_u *s = utf16_to_enc(p, NULL); - if (s != NULL) - { - semsg(_(e_illegal_str_name_str_in_font_name_str), - "charset", s, name); - vim_free(s); - } + lf->lfCharSet = charset_pairs[i].charset; + p += charset_pairs[i].name.length; break; } - break; } + + if (i == (int)ARRAY_LENGTH(charset_pairs) && verbose) + { + char_u *s = utf16_to_enc(p, NULL); + if (s != NULL) + { + semsg(_(e_illegal_str_name_str_in_font_name_str), + "charset", s, name); + vim_free(s); + } + } + break; case L'q': + for (i = 0; i < (int)ARRAY_LENGTH(quality_pairs); ++i) { - struct quality_pair *qp; - - for (qp = quality_pairs; qp->name != NULL; ++qp) - if (utf16ascncmp(p, qp->name, strlen(qp->name)) == 0) - { - lf->lfQuality = qp->quality; - p += strlen(qp->name); - break; - } - if (qp->name == NULL && verbose) + if (utf16ascncmp(p, (char *)quality_pairs[i].name.string, + quality_pairs[i].name.length) == 0) { - char_u *s = utf16_to_enc(p, NULL); - if (s != NULL) - { - semsg(_(e_illegal_str_name_str_in_font_name_str), - "quality", s, name); - vim_free(s); - } + lf->lfQuality = quality_pairs[i].quality; + p += quality_pairs[i].name.length; break; } - break; } + + if (i == (int)ARRAY_LENGTH(quality_pairs) && verbose) + { + char_u *s = utf16_to_enc(p, NULL); + if (s != NULL) + { + semsg(_(e_illegal_str_name_str_in_font_name_str), + "quality", s, name); + vim_free(s); + } + } + break; default: if (verbose) semsg(_(e_illegal_char_nr_in_font_name_str), p[-1], name); diff --git a/src/version.c b/src/version.c index 64308dc43..e05f6172d 100644 --- a/src/version.c +++ b/src/version.c @@ -704,6 +704,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1365, /**/ 1364, /**/ -- -- You received this message from the "vim_dev" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php --- You received this message because you are subscribed to the Google Groups "vim_dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscr...@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/vim_dev/E1uBfVO-0081tq-GW%40256bit.org.