From 1c76cad5efc61fafc1f1147c30d500d208efd4fd Mon Sep 17 00:00:00 2001 From: bulk88 Date: Wed, 8 May 2024 03:30:19 -0400 Subject: [PATCH 1/2] restore Visual C 6 and newer but older VC 200X builds rv:2 -remove mixed declarations and code -"long long"->"intmax_t", "long long" is from C99, that is too new for older 2000s or 2010s versions MS VCs, so switch to gnumake specific "intmax_t" type which I think is always 64 bits, all OSes, but "intmax_t" is "portable", and can be redefined per platform by gnumake, to CC specific types, like for MSVC's very old "__int64" and well supported by all VC versions -switch from too new "intptr_t" type for VC6-2010 era VCs, to "size_t" for storing pointer-like data in "int"/numeric C types, in job.c and function.c. HANDLE is always a void * typedef on Win32. HANDLE is 32b on 32b WinOS, and 64b on 64b OS. "size_t" fits better and is older/more supported, for 32b vs 64b pointers builds vs trying to shim a compat typedef to 32b on 32b, 64 on 64, and then putting new gnumake-specific macros and cast tokens everywhere, size_t is more readable vs program specific or OS specific tokens. -in w32err.c in map_windows32_error_to_string() switch from the inefficient wsprintf() to snprintf(), wsprintf is really wsprintfA from user32.dll, and map_windows32_error_to_string:wsprintf was the ONLY linking dependency of mingw gnumake and visual c gnumake to user32.dll. user32 is a GUI library, and a bit illogical to load over and over on process start up for the short running and high process start frequency gnumake, there is startup CPU overhead, disk/FS I/O and permanently allocated private memory pages overhead (C RW globals in each DLL) for every dll. This is an optimization, for process start up speed. map_windows32_error_to_string:wsprintf code git blames to SHA-1: e7a525c5d53029de18871890196b665c803e98d3 * Wed May 15 10:14:14 CDT 1996 Rob Tulloh * w32/subproc/w32err.c: WIN32: subproc library support code which is initial commit of w32err.c -snprintf() is >=VC 2015, and MS specific _snprintf() has non-compatible behavior with its retval vs ANSI/ISO/POSIX so write a shim around _snprintf() making it more like POSIX _snprintf(), just in case, even thought I dont see user supplied strings being passed right now in gnumake that could cause a buffer overflow, in future, in gnumake's code base, who knows, someone else might write code that depends on the retval char count more than right now, so best idea is just write a defensive shim for compat for MSVC over --- src/config.h.W32 | 13 +++- src/dir.c | 4 +- src/function.c | 12 ++-- src/job.c | 4 +- src/main.c | 6 +- src/makeint.h | 40 ++++++++++- src/misc.c | 4 +- src/posixos.c | 2 +- src/remake.c | 45 +++++++++--- src/variable.c | 2 +- src/variable.h | 2 +- src/w32/include/dirent.h | 5 ++ src/w32/subproc/sub_proc.c | 29 ++++---- src/w32/subproc/w32err.c | 2 +- src/w32/w32os.c | 143 +++++++++++++++++++++++++++++++++++-- src/warning.c | 12 ++-- 16 files changed, 267 insertions(+), 58 deletions(-) diff --git a/src/config.h.W32 b/src/config.h.W32 index 7dbe2ab0..b2747cbe 100644 --- a/src/config.h.W32 +++ b/src/config.h.W32 @@ -23,7 +23,9 @@ this program. If not, see . */ /* Suppress some Visual C++ warnings. Maybe after the code cleanup for ISO C we can remove some/all of these. */ #if _MSC_VER > 1000 +# pragma warning(disable:4091) /* ignored on left of ‘MyEnum’ when no variable is declared*/ # pragma warning(disable:4100) /* unreferenced formal parameter */ +# pragma warning(disable:4127) /* conditional expression is constant "while(1)" */ # pragma warning(disable:4130) /* logical operation on address of string constant */ # pragma warning(disable:4131) /* uses old-style declarator */ # pragma warning(disable:4702) /* unreachable code */ @@ -342,7 +344,7 @@ this program. If not, see . */ /* Define to 1 if you have the `strtoll' function. */ #define HAVE_STRTOLL 1 -#ifdef __TINYC__ +#if defined (__TINYC__) || (defined(_MSC_VER) && _MSC_VER < 1800) # ifndef strtoll # define strtoll _strtoi64 # endif @@ -576,8 +578,13 @@ char *ttyname (int); /* Define {u,}intmax_t if not defined in or . */ #if !HAVE_STDINT_H && !HAVE_INTTYPES_H -#define intmax_t long long -#define uintmax_t unsigned long long +# ifdef _MSC_VER +# define intmax_t __int64 +# define uintmax_t unsigned __int64 +# else +# define intmax_t long long +# define uintmax_t unsigned long long +# endif #endif /* Define if you have that is POSIX.1 compatible. */ diff --git a/src/dir.c b/src/dir.c index a805a377..91fd4c33 100644 --- a/src/dir.c +++ b/src/dir.c @@ -1106,7 +1106,7 @@ print_dir_data_base (void) #if MK_OS_W32 printf (_("# %s (key %s, mtime %s): could not be opened.\n"), dir->name, dir->contents->path_key, - make_ulltoa ((unsigned long long)dir->contents->mtime, buf)); + make_ulltoa ((uintmax_t)dir->contents->mtime, buf)); #elif defined(VMS_INO_T) printf (_("# %s (device %d, inode [%d,%d,%d]): could not be opened.\n"), dir->name, dir->contents->dev, @@ -1139,7 +1139,7 @@ print_dir_data_base (void) #if MK_OS_W32 printf (_("# %s (key %s, mtime %s): "), dir->name, dir->contents->path_key, - make_ulltoa ((unsigned long long)dir->contents->mtime, buf)); + make_ulltoa ((uintmax_t)dir->contents->mtime, buf)); #elif defined(VMS_INO_T) printf (_("# %s (device %d, inode [%d,%d,%d]): "), dir->name, dir->contents->dev, diff --git a/src/function.c b/src/function.c index 82a9fe26..52043f7e 100644 --- a/src/function.c +++ b/src/function.c @@ -758,13 +758,13 @@ strip_whitespace (const char **begpp, const char **endpp) return (char *)*begpp; } -static long long +static intmax_t parse_numeric (const char *s, const char *msg) { const char *beg = s; const char *end = s + strlen (s) - 1; char *endp; - long long num; + intmax_t num; strip_whitespace (&beg, &end); if (beg > end) @@ -786,7 +786,7 @@ func_word (char *o, char **argv, const char *funcname UNUSED) { const char *end_p; const char *p; - long long i; + intmax_t i; i = parse_numeric (argv[0], _("invalid first argument to 'word' function")); @@ -809,7 +809,7 @@ static char * func_wordlist (char *o, char **argv, const char *funcname UNUSED) { char buf[INTSTR_LENGTH + 1]; - long long start, stop, count; + intmax_t start, stop, count; const char* badfirst = _("invalid first argument to 'wordlist' function"); const char* badsecond = _("invalid second argument to 'wordlist' function"); @@ -1723,10 +1723,10 @@ windows32_openpipe (int *pipedes, int errfd, pid_t *pid_p, char **command_argv, *pid_p = (pid_t) hProcess; /* set up to read data from child */ - pipedes[0] = _open_osfhandle ((intptr_t) hChildOutRd, O_RDONLY); + pipedes[0] = _open_osfhandle ((size_t) hChildOutRd, O_RDONLY); /* this will be closed almost right away */ - pipedes[1] = _open_osfhandle ((intptr_t) hChildOutWr, O_APPEND); + pipedes[1] = _open_osfhandle ((size_t) hChildOutWr, O_APPEND); return 0; } else diff --git a/src/job.c b/src/job.c index 09fe9d16..03808cd0 100644 --- a/src/job.c +++ b/src/job.c @@ -22,6 +22,8 @@ this program. If not, see . */ /* Default shell to use. */ #if MK_OS_W32 # include +/* for WSABASEERR, 2000s/2010s Win OS CC headers don't auto #include winsock2.h */ +# include const char *default_shell = "sh.exe"; int no_default_sh_exe = 1; @@ -346,7 +348,7 @@ create_batch_file (char const *base, int unixy, int *fd) const unsigned final_size = path_size + size + 1; char *const path = xmalloc (final_size); memcpy (path, temp_path, final_size); - *fd = _open_osfhandle ((intptr_t)h, 0); + *fd = _open_osfhandle ((size_t)h, 0); if (unixy) { char *p; diff --git a/src/main.c b/src/main.c index 15104212..36bd5cec 100644 --- a/src/main.c +++ b/src/main.c @@ -3360,9 +3360,11 @@ decode_switches (int argc, const char **argv, enum variable_origin origin) warn_undefined_variables_flag = 0; } - if (warn_flags) - for (const char **pp = warn_flags->list; *pp; ++pp) + if (warn_flags) { + const char **pp; + for (pp = warn_flags->list; *pp; ++pp) decode_warn_actions (*pp, NULL); + } /* Perform any special switch handling. */ run_silent = silent_flag; diff --git a/src/makeint.h b/src/makeint.h index 5a553093..479afb0e 100644 --- a/src/makeint.h +++ b/src/makeint.h @@ -306,6 +306,42 @@ char *strerror (int errnum); #endif #define FILE_TIMESTAMP uintmax_t +#if (defined(_MSC_VER) && (_MSC_VER < 1900)) +/* must use shim on all < VC 2015 see + https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/snprintf-snprintf-snprintf-l-snwprintf-snwprintf-l?view=msvc-170 + + MS docs says ISO snprintf() fn/sym not available before VC 2015, and + docs say MS's vendor specific _snprintf(), is not ISO compatible and is not + a drop in for ISO C's snprintf(), specifically about retval of the + 2 functions, and _snprintf()'s buffer behaviour when + caller's char [] char * is too short +*/ +#define snprintf _snprintf_c99 + +int _snprintf_c99( + char * dest, + size_t count, + const char * format, + ...); + +#endif + + +#define HAVE_STRTOLL 1 +#if defined (__TINYC__) || (defined(_MSC_VER) && _MSC_VER < 1800) +# ifndef strtoll +# define strtoll _strtoi64 +# endif +# ifndef strtoull +# define strtoull _strtoui64 +# endif +#endif + +#if defined(_MSC_VER) && (_MSC_VER < 1300) +# define _strtoi64 _strtoi64_vc +__int64 _strtoi64_vc(const char *nptr, char **endptr, int base); +#endif + #if !defined(HAVE_STRSIGNAL) char *strsignal (int signum); #endif @@ -583,8 +619,8 @@ void pfatal_with_name (const char *) NORETURN; void perror_with_name (const char *, const char *); #define xstrlen(_s) ((_s)==NULL ? 0 : strlen (_s)) unsigned int make_toui (const char*, const char**); -char *make_lltoa (long long, char *); -char *make_ulltoa (unsigned long long, char *); +char *make_lltoa (intmax_t, char *); +char *make_ulltoa (uintmax_t, char *); void make_seed (unsigned int); unsigned int make_rand (void); pid_t make_pid (void); diff --git a/src/misc.c b/src/misc.c index a53301df..52ce52db 100644 --- a/src/misc.c +++ b/src/misc.c @@ -63,14 +63,14 @@ make_toui (const char *str, const char **error) We can't use standard PRI* here: those are based on intNN_t types. */ char * -make_lltoa (long long val, char *buf) +make_lltoa (intmax_t val, char *buf) { sprintf (buf, "%" MK_PRI64_PREFIX "d", val); return buf; } char * -make_ulltoa (unsigned long long val, char *buf) +make_ulltoa (uintmax_t val, char *buf) { sprintf (buf, "%" MK_PRI64_PREFIX "u", val); return buf; diff --git a/src/posixos.c b/src/posixos.c index 6b0b716e..c74db3f0 100644 --- a/src/posixos.c +++ b/src/posixos.c @@ -160,7 +160,7 @@ jobserver_setup (int slots, const char *style) fifo_name = xmalloc (strlen (tmpdir) + CSTRLEN (FNAME_PREFIX) + INTSTR_LENGTH + 2); sprintf (fifo_name, "%s/" FNAME_PREFIX "%03" MK_PRI64_PREFIX "d", - tmpdir, (long long)make_pid ()); + tmpdir, (intmax_t)make_pid ()); EINTRLOOP (r, mkfifo (fifo_name, 0600)); if (r < 0) diff --git a/src/remake.c b/src/remake.c index ee8971e7..6385e86c 100644 --- a/src/remake.c +++ b/src/remake.c @@ -37,12 +37,37 @@ this program. If not, see . */ #include #include #include -#if defined(_MSC_VER) && _MSC_VER > 1200 + +# if defined(_MSC_VER) +# if MSC_VER > 1200 /* VC7 or later supports _stat64 to access 64-bit file size. */ -#define STAT _stat64 -#else -#define STAT stat -#endif +# define STAT _stat64 +# define U64_TO_DBL_VC(u64) ((double)(u64)) +# else +/* is VC 6*/ +# define STAT stat +/* Old MS compilers do not implement the double->uint64 conversion and + * silently do a double->int64 conversion instead. See + * http://connect.microsoft.com/VisualStudio/feedback/details/270762/error-in-converting-double-to-unsigned-long-long */ +# define U64_TO_DBL_VC(nv) u64_to_dbl_vc(nv) + +/* don't trust atof, so generate 2**-32 from simpler constants and + * hope the VC optimizer will do its work properly */ + + +#define DBL_0x1p16 ((double)65536) +#define DBL_0x1p32 (DBL_0x1p16 * DBL_0x1p16) + static double + u64_to_dbl_vc(unsigned __int64 u64) { + unsigned long h = u64 >> 32; + unsigned long l = u64 & 0xffffffff; + return (DBL_0x1p32 * h) + (double)l; + } +# endif +/* Win32 but not VC */ +# else +# define U64_TO_DBL_VC(u64) ((double)(u64)) +# endif #endif @@ -1526,9 +1551,13 @@ f_mtime (struct file *file, int search) if (adjusted_now < adjusted_mtime) { double from_now = - (FILE_TIMESTAMP_S (mtime) - FILE_TIMESTAMP_S (now) - + ((FILE_TIMESTAMP_NS (mtime) - FILE_TIMESTAMP_NS (now)) - / 1e9)); + U64_TO_DBL_VC(( + FILE_TIMESTAMP_S (mtime) + - FILE_TIMESTAMP_S (now) + + (FILE_TIMESTAMP)(( + (FILE_TIMESTAMP_NS (mtime) - FILE_TIMESTAMP_NS (now)) / 1e9 + )) + )); char from_now_string[100]; if (from_now >= 100.0 && from_now < (double) ULONG_MAX) diff --git a/src/variable.c b/src/variable.c index af3d6a40..5726386e 100644 --- a/src/variable.c +++ b/src/variable.c @@ -33,7 +33,7 @@ this program. If not, see . */ #include "warning.h" /* Incremented every time we enter target_environment(). */ -unsigned long long env_recursion = 0; +uintmax_t env_recursion = 0; /* Incremented every time we add or remove a global variable. */ static unsigned long variable_changenum = 0; diff --git a/src/variable.h b/src/variable.h index 9cedebcd..5a59d6b1 100644 --- a/src/variable.h +++ b/src/variable.h @@ -120,7 +120,7 @@ struct pattern_var struct variable variable; }; -extern unsigned long long env_recursion; +extern uintmax_t env_recursion; extern char *variable_buffer; extern struct variable_set_list *current_variable_set_list; extern struct variable *default_goal_var; diff --git a/src/w32/include/dirent.h b/src/w32/include/dirent.h index 0de53970..1dd467d9 100644 --- a/src/w32/include/dirent.h +++ b/src/w32/include/dirent.h @@ -27,6 +27,11 @@ this program. If not, see . */ #include #include +/* missing in VC 6 */ +#ifndef FILE_ATTRIBUTE_DEVICE +# define FILE_ATTRIBUTE_DEVICE 64 +#endif + #ifndef NAME_MAX #define NAME_MAX 255 #endif diff --git a/src/w32/subproc/sub_proc.c b/src/w32/subproc/sub_proc.c index ad9e2570..2366ec73 100644 --- a/src/w32/subproc/sub_proc.c +++ b/src/w32/subproc/sub_proc.c @@ -20,11 +20,6 @@ this program. If not, see . */ #include #include #include /* for _get_osfhandle */ -#ifdef _MSC_VER -# include /* for intptr_t */ -#else -# include -#endif #include #include /* for msvc _beginthreadex, _endthreadex */ #include @@ -47,9 +42,9 @@ this program. If not, see . */ static char *make_command_line(char *shell_name, char *exec_path, char **argv); typedef struct sub_process_t { - intptr_t sv_stdin[2]; - intptr_t sv_stdout[2]; - intptr_t sv_stderr[2]; + void * sv_stdin[2]; + void * sv_stdout[2]; + void * sv_stderr[2]; int using_pipes; char *inp; DWORD incnt; @@ -436,12 +431,12 @@ process_init() pproc->lerrno = E_SCALL; return((HANDLE)pproc); } - pproc->sv_stdin[0] = (intptr_t) stdin_pipes[0]; - pproc->sv_stdin[1] = (intptr_t) stdin_pipes[1]; - pproc->sv_stdout[0] = (intptr_t) stdout_pipes[0]; - pproc->sv_stdout[1] = (intptr_t) stdout_pipes[1]; - pproc->sv_stderr[0] = (intptr_t) stderr_pipes[0]; - pproc->sv_stderr[1] = (intptr_t) stderr_pipes[1]; + pproc->sv_stdin[0] = (void *) stdin_pipes[0]; + pproc->sv_stdin[1] = (void *) stdin_pipes[1]; + pproc->sv_stdout[0] = (void *) stdout_pipes[0]; + pproc->sv_stdout[1] = (void *) stdout_pipes[1]; + pproc->sv_stderr[0] = (void *) stderr_pipes[0]; + pproc->sv_stderr[1] = (void *) stderr_pipes[1]; pproc->using_pipes = 1; @@ -464,9 +459,9 @@ process_init_fd(HANDLE stdinh, HANDLE stdouth, HANDLE stderrh) * Just pass the provided file handles to the 'child * side' of the pipe, bypassing pipes altogether. */ - pproc->sv_stdin[1] = (intptr_t) stdinh; - pproc->sv_stdout[1] = (intptr_t) stdouth; - pproc->sv_stderr[1] = (intptr_t) stderrh; + pproc->sv_stdin[1] = (void *) stdinh; + pproc->sv_stdout[1] = (void *) stdouth; + pproc->sv_stderr[1] = (void *) stderrh; pproc->last_err = pproc->lerrno = 0; } diff --git a/src/w32/subproc/w32err.c b/src/w32/subproc/w32err.c index ddcfa5d5..f5b48a89 100644 --- a/src/w32/subproc/w32err.c +++ b/src/w32/subproc/w32err.c @@ -50,7 +50,7 @@ map_windows32_error_to_string (DWORD ercode) { /* Fill message buffer with a default message in * case FormatMessage fails */ - wsprintf (szMessageBuffer, "Error %ld", ercode); + snprintf (szMessageBuffer, sizeof(szMessageBuffer)-1, "Error %ld", ercode); /* * Special code for winsock error handling. diff --git a/src/w32/w32os.c b/src/w32/w32os.c index af02621e..2329948b 100644 --- a/src/w32/w32os.c +++ b/src/w32/w32os.c @@ -170,7 +170,7 @@ os_anontmp () NULL); /* no template file */ if (h != INVALID_HANDLE_VALUE) - return _open_osfhandle ((intptr_t)h, 0); + return _open_osfhandle ((size_t)h, 0); { const DWORD er = GetLastError (); @@ -434,7 +434,7 @@ osync_get_mutex () /* Prepare the mutex handle string for our children. 2 hex digits per byte + 2 characters for "0x" + null. */ mutex = xmalloc ((2 * sizeof (osync_handle)) + 2 + 1); - sprintf (mutex, "0x%Ix", (unsigned long long)(DWORD_PTR)osync_handle); + sprintf (mutex, "0x%Ix", (size_t)osync_handle); } return mutex; @@ -444,17 +444,22 @@ unsigned int osync_parse_mutex (const char *mutex) { char *endp; - unsigned long long i; + HANDLE h; errno = 0; - i = strtoull (mutex, &endp, 16); + /* type HANDLE is 4 bytes on 32b OS, 8 bytes on 64b OS */ +#if defined _WIN64 + h = (HANDLE) strtoull (mutex, &endp, 16); +#else + h = (HANDLE) strtoul (mutex, &endp, 16); +#endif if (errno != 0) OSS (fatal, NILF, _("cannot parse output sync mutex %s: %s"), mutex, strerror (errno)); if (endp[0] != '\0') OS (fatal, NILF, _("invalid output sync mutex: %s"), mutex); - osync_handle = (HANDLE) (DWORD_PTR) i; + osync_handle = h; return 1; } @@ -527,6 +532,130 @@ get_handle_for_fd (int fd) { /* This funcion call is needed to get around the "bad-function-cast"-warning emitted by GCC when casting and assigning in the same statement. */ - intptr_t fh = _get_osfhandle (fd); - return (HANDLE) fh; + HANDLE fh = (HANDLE) _get_osfhandle (fd); + return fh; +} + +#if (defined(_MSC_VER) && (_MSC_VER < 1900)) +int _snprintf_c99( + char * dest, + size_t count, + const char * format, + ...) { + va_list args; + int result; + char * get_len_buf; + + va_start(args, format); + result = _vsnprintf( + dest, + count - 1, + format, + args + ); + if (result < 0) { + dest[count] = '\0'; + get_len_buf = alloca(1024); + result = _vsnprintf(get_len_buf, 1023, format, args); + if (result >= 0 && result < 1023) { + result = strlen(get_len_buf); + } else { + /* don't bother with malloc/strlen in a loop + if this is reached, something is wrong, 1KB is enough + */ + O (fatal, NILF, _("_snprintf_c99 output too big")); + result = -1; + } + } + va_end(args); + return result; +} +#endif + + +/*VC 6 doesn't have strtoi64, VC 7/2003 does */ +#if defined(_MSC_VER) && (_MSC_VER < 1300) +/* from ReactOS /sdk/lib/crt/string/strtoi64.c + https://git.reactos.org/?p=reactos.git;a=blob;f=COPYING3;hb=HEAD +*/ +/* Based on Wine Staging 1.9.9 - dlls/msvcrt/string.c */ + +/********************************************************************* +* _strtoi64_l (MSVCRT.@) +* +*/ +__int64 _strtoi64_vc(const char *nptr, char **endptr, int base) +{ + const char *p = nptr; + BOOL negative = FALSE; + BOOL got_digit = FALSE; + __int64 ret = 0; + + + if ( + !(nptr != NULL) + || !(base == 0 || base >= 2) + || !(base <= 36) + ) { + *_errno() = EINVAL; + return 0; + } + + while (isspace(*nptr)) nptr++; + + if(*nptr == '-') { + negative = TRUE; + nptr++; + } else if(*nptr == '+') + nptr++; + + if((base==0 || base==16) && *nptr=='0' && tolower(*(nptr+1))=='x') { + base = 16; + nptr += 2; + } + + if(base == 0) { + if(*nptr=='0') + base = 8; + else + base = 10; + } + + while(*nptr) { + char cur = tolower(*nptr); + int v; + + if(isdigit(cur)) { + if(cur >= '0'+base) + break; + v = cur-'0'; + } else { + if(cur<'a' || cur>='a'+base-10) + break; + v = cur-'a'+10; + } + got_digit = TRUE; + + if(negative) + v = -v; + + nptr++; + + if(!negative && (ret>_I64_MAX/base || ret*base>_I64_MAX-v)) { + ret = _I64_MAX; + *_errno() = ERANGE; + } + else if (negative && (ret<_I64_MIN / base || ret*base<_I64_MIN - v)) { + ret = _I64_MIN; + *_errno() = ERANGE; + } + else + ret = ret*base + v; + } + + if(endptr) + *endptr = (char*)(got_digit ? nptr : p); + + return ret; } +#endif diff --git a/src/warning.c b/src/warning.c index 35950f77..634137f2 100644 --- a/src/warning.c +++ b/src/warning.c @@ -44,8 +44,9 @@ static const char *w_name_map[wt_max] = { static void set_warnings () { + enum warning_type wt = 0; /* Called whenever any warnings could change; resets the current actions. */ - for (enum warning_type wt = 0; wt < wt_max; ++wt) + for (; wt < wt_max; ++wt) warnings[wt] = warn_flag.actions[wt] != w_unset ? warn_flag.actions[wt] : warn_flag.global != w_unset ? warn_flag.global @@ -73,15 +74,17 @@ warn_init () static void init_data (struct warning_data *data) { + enum warning_type wt = wt_invalid_var; data->global = w_unset; - for (enum warning_type wt = wt_invalid_var; wt < wt_max; ++wt) + for (; wt < wt_max; ++wt) data->actions[wt] = w_unset; } static enum warning_action decode_warn_action (const char *action, size_t length) { - for (enum warning_action st = w_ignore; st <= w_error; ++st) + enum warning_action st = w_ignore; + for (; st <= w_error; ++st) { size_t len = strlen (w_action_map[st]); if (length == len && strncasecmp (action, w_action_map[st], length) == 0) @@ -94,7 +97,8 @@ decode_warn_action (const char *action, size_t length) static enum warning_type decode_warn_name (const char *name, size_t length) { - for (enum warning_type wt = wt_invalid_var; wt < wt_max; ++wt) + enum warning_type wt = wt_invalid_var; + for (; wt < wt_max; ++wt) { size_t len = strlen (w_name_map[wt]); if (length == len && strncasecmp (name, w_name_map[wt], length) == 0) -- 2.35.1.windows.2