LCOV - code coverage report
Current view: top level - asar - warnings.cpp (source / functions) Coverage Total Hit
Test: asar.info Lines: 91.2 % 57 52
Test Date: 2024-01-15 16:23:49 Functions: 87.5 % 8 7
Branches: 77.5 % 40 31

             Branch data     Line data    Source code
       1                 :             : #include "warnings.h"
       2                 :             : 
       3                 :             : #include "asar.h"
       4                 :             : #include <assert.h>
       5                 :             : #include <stdarg.h>
       6                 :             : 
       7                 :             : #include "interface-shared.h"
       8                 :             : 
       9                 :             : static int asar_num_warnings = 0;
      10                 :             : bool suppress_all_warnings = false;
      11                 :             : 
      12                 :             : struct asar_warning_mapping
      13                 :             : {
      14                 :             :         asar_warning_id warnid;
      15                 :             :         const char* name;
      16                 :             :         const char* message;
      17                 :             :         bool enabled;
      18                 :             :         bool enabled_default;
      19                 :             : 
      20                 :             :         asar_warning_mapping(asar_warning_id inwarnid, const char *iname, const char* inmessage, bool inenabled = true)
      21                 :             :         {
      22                 :             :                 ++asar_num_warnings;
      23                 :             : 
      24                 :             :                 warnid = inwarnid;
      25                 :             :                 name = iname;
      26                 :             :                 message = inmessage;
      27                 :             :                 enabled = inenabled;
      28                 :             :                 enabled_default = inenabled;
      29                 :             : 
      30                 :             :                 // RPG Hacker: Sanity check. This makes sure that the order
      31                 :             :                 // of entries in asar_warnings matches with the order of
      32                 :             :                 // constants in asar_warning_id. This is important because
      33                 :             :                 // we access asar_warnings as an array.
      34                 :             :                 // Would love to do this via static_assert(), but can't
      35                 :             :                 // think of a way to do so.
      36                 :             :                 assert(warnid - warning_id_start == asar_num_warnings);
      37                 :             :         }
      38                 :             : };
      39                 :             : 
      40                 :             : // Keep in sync with asar_warning_id.
      41                 :             : // Both, enum mapping and order, must match.
      42                 :             : #define WRN(name) warning_id_ ## name, "W" #name
      43                 :             : static asar_warning_mapping asar_warnings[] =
      44                 :             : {
      45                 :             :         { WRN(relative_path_used), "Relative %s path passed to asar_patch_ex() - please use absolute paths only to prevent undefined behavior!" },
      46                 :             : 
      47                 :             :         { WRN(rom_too_short), "ROM is too short to have a title. (Expected '%s')" },
      48                 :             :         { WRN(rom_title_incorrect), "ROM title is incorrect. Expected '%s', got '%s'." },
      49                 :             : 
      50                 :             :         { WRN(65816_yy_x_does_not_exist), "($yy),x does not exist, assuming $yy,x." },
      51                 :             :         { WRN(65816_xx_y_assume_16_bit), "%s $xx,y is not valid with 8-bit parameters, assuming 16-bit." },
      52                 :             :         { WRN(spc700_assuming_8_bit), "This opcode does not exist with 16-bit parameters, assuming 8-bit." },
      53                 :             : 
      54                 :             :         { WRN(cross_platform_path), "This patch may not assemble cleanly on all platforms. Please use / instead." },
      55                 :             : 
      56                 :             :         { WRN(missing_org), "Missing org or freespace command." },
      57                 :             :         { WRN(set_middle_byte), "It would be wise to set the 008000 bit of this address." },
      58                 :             : 
      59                 :             :         { WRN(unrecognized_special_command), "Unrecognized special command - your version of Asar might be outdated." },
      60                 :             : 
      61                 :             :         { WRN(freespace_leaked), "This freespace appears to be leaked." },
      62                 :             : 
      63                 :             :         { WRN(warn_command), "warn command%s" },
      64                 :             : 
      65                 :             :         { WRN(implicitly_sized_immediate), "Implicitly sized immediate.", false },
      66                 :             : 
      67                 :             :         { WRN(xkas_deprecated), "xkas support is being deprecated and will be removed in a future version of Asar. Please use an older version of Asar (<=1.50) if you need it." },
      68                 :             :         { WRN(xkas_eat_parentheses), "xkas compatibility warning: Unlike xkas, Asar does not eat parentheses after defines." },
      69                 :             :         { WRN(xkas_label_access), "xkas compatibility warning: Label access is always 24bit in emulation mode, but may be 16bit in native mode." },
      70                 :             :         { WRN(xkas_warnpc_relaxed), "xkas conversion warning : warnpc is relaxed one byte in Asar." },
      71                 :             :         { WRN(xkas_style_conditional), "xkas-style conditional compilation detected. Please use the if command instead." },
      72                 :             :         { WRN(xkas_patch), "If you want to assemble an xkas patch, add ;@xkas at the top or you may run into a couple of problems." },
      73                 :             :         { WRN(xkas_incsrc_relative), "xkas compatibility warning: incsrc and incbin look for files relative to the patch in Asar, but xkas looks relative to the assembler." },
      74                 :             :         { WRN(convert_to_asar), "Convert the patch to native Asar format instead of making an Asar-only xkas patch." },
      75                 :             : 
      76                 :             :         { WRN(fixed_deprecated), "the 'fixed' parameter on freespace/freecode/freedata is deprecated - please use 'static' instead." },
      77                 :             : 
      78                 :             :         { WRN(autoclear_deprecated), "'autoclear' is deprecated - please use 'autoclean' instead." },
      79                 :             : 
      80                 :             :         { WRN(check_memory_file), "Accessing file '%s' which is not in memory while W%d is enabled.", false },
      81                 :             : 
      82                 :             :         { WRN(if_not_condition_deprecated), "'if !condition' is deprecated - please use 'if not(condition)' instead." },
      83                 :             : 
      84                 :             :         { WRN(function_redefined), "Function '%s' redefined." },
      85                 :             : 
      86                 :             :         { WRN(datasize_last_label), "Datasize used on last detected label '%s'." },
      87                 :             :         { WRN(datasize_exceeds_size), "Datasize exceeds 0xFFFF for label '%s'." },
      88                 :             : 
      89                 :             :         { WRN(mapper_already_set), "A mapper has already been selected." },
      90                 :             :         { WRN(feature_deprecated), "DEPRECATION NOTIFICATION: Feature \"%s\" is deprecated and will be REMOVED in the future. Please update your code to conform to newer styles. Suggested work around: %s." },
      91                 :             : 
      92                 :             :         { WRN(byte_order_mark_utf8), "UTF-8 byte order mark detected and skipped." },
      93                 :             : };
      94                 :             : 
      95                 :             : // RPG Hacker: Sanity check. This makes sure that the element count of asar_warnings
      96                 :             : // matches with the number of constants in asar_warning_id. This is important, because
      97                 :             : // we are going to access asar_warnings as an array.
      98                 :             : static_assert(sizeof(asar_warnings) / sizeof(asar_warnings[0]) == warning_id_count, "asar_warnings and asar_warning_id are not in sync");
      99                 :             : 
     100                 :         427 : void asar_throw_warning(int whichpass, asar_warning_id warnid, ...)
     101                 :             : {
     102   [ +  +  +  + ]:         427 :         if (pass == whichpass && !suppress_all_warnings)
     103                 :             :         {
     104                 :             :                 assert(warnid > warning_id_start && warnid < warning_id_end);
     105                 :             : 
     106                 :         188 :                 const asar_warning_mapping& warning = asar_warnings[warnid - warning_id_start - 1];
     107                 :             : 
     108         [ +  + ]:         188 :                 if (warning.enabled)
     109                 :             :                 {
     110                 :             :                         char warning_buffer[1024];
     111                 :             :                         va_list args;
     112                 :          44 :                         va_start(args, warnid);
     113                 :             : 
     114                 :             : #if defined(__clang__)
     115                 :             : #       pragma clang diagnostic push
     116                 :             : // "format string is not a literal".
     117                 :             : // The pointer we're passing here should always point to a string literal,
     118                 :             : // thus, I think, we can safely ignore this here.
     119                 :             : #       pragma clang diagnostic ignored "-Wformat-nonliteral"
     120                 :             : #endif
     121                 :             : 
     122                 :          44 :                         vsnprintf(warning_buffer, sizeof(warning_buffer), warning.message, args);
     123                 :             : 
     124                 :             : #if defined(__clang__)
     125                 :             : #       pragma clang diagnostic pop
     126                 :             : #endif
     127                 :             : 
     128                 :          44 :                         va_end(args);
     129                 :          44 :                         warn((int)warnid, warning_buffer);
     130                 :             :                 }
     131                 :             :         }
     132                 :         427 : }
     133                 :             : 
     134                 :          44 : const char* get_warning_name(asar_warning_id warnid)
     135                 :             : {
     136                 :             :         assert(warnid > warning_id_start && warnid < warning_id_end);
     137                 :             : 
     138                 :          44 :         const asar_warning_mapping& warning = asar_warnings[warnid - warning_id_start - 1];
     139                 :             : 
     140                 :          44 :         return warning.name;
     141                 :             : }
     142                 :             : 
     143                 :             : 
     144                 :             : 
     145                 :          36 : void set_warning_enabled(asar_warning_id warnid, bool enabled)
     146                 :             : {
     147                 :             :         assert(warnid > warning_id_start && warnid < warning_id_end);
     148                 :             : 
     149                 :          36 :         asar_warning_mapping& warning = asar_warnings[warnid - warning_id_start - 1];
     150                 :             : 
     151                 :          36 :         warning.enabled = enabled;
     152                 :          36 : }
     153                 :             : 
     154                 :          36 : asar_warning_id parse_warning_id_from_string(const char* string)
     155                 :             : {
     156                 :             :         const char* pos = string;
     157                 :             : 
     158         [ -  + ]:          36 :         if (pos == nullptr)
     159                 :             :         {
     160                 :             :                 return warning_id_end;
     161                 :             :         }
     162                 :             : 
     163                 :             : 
     164   [ +  -  +  - ]:          36 :         if (pos[0] == 'w' || pos[0] == 'W')
     165                 :             :         {
     166                 :          36 :                 ++pos;
     167                 :             :         }
     168         [ +  + ]:         702 :         for(int i = 0; i < warning_id_end-warning_id_start-1; i++)
     169                 :             :         {
     170         [ +  + ]:         699 :                 if(!stricmpwithlower(pos, asar_warnings[i].name+1))
     171                 :             :                 {
     172                 :          33 :                         return asar_warnings[i].warnid;
     173                 :             :                 }
     174                 :             :         }
     175                 :           3 :         char* endpos = nullptr;
     176                 :           3 :         int numid = (int)strtol(pos, &endpos, 10);
     177                 :             : 
     178   [ -  +  -  + ]:           3 :         if (endpos == nullptr || endpos[0] != '\0')
     179                 :             :         {
     180                 :             :                 return warning_id_end;
     181                 :             :         }
     182                 :             : 
     183                 :             :         asar_warning_id warnid = (asar_warning_id)numid;
     184                 :             : 
     185         [ -  + ]:           3 :         if (warnid <= warning_id_start || warnid >= warning_id_end)
     186                 :             :         {
     187                 :             :                 return warning_id_end;
     188                 :             :         }
     189                 :             : 
     190                 :           3 :         asar_throw_warning(1, warning_id_feature_deprecated, "Numerical warnings", "Please transition to Wwarning_name");
     191                 :             :         return warnid;
     192                 :             : }
     193                 :             : 
     194                 :           0 : void reset_warnings_to_default()
     195                 :             : {
     196         [ #  # ]:           0 :         for (int i = (int)(warning_id_start + 1); i < (int)warning_id_end; ++i)
     197                 :             :         {
     198                 :           0 :                 asar_warning_mapping& warning = asar_warnings[i - (int)warning_id_start - 1];
     199                 :             : 
     200                 :           0 :                 warning.enabled = warning.enabled_default;
     201                 :             :         }
     202                 :           0 : }
     203                 :             : 
     204                 :             : struct warnings_state
     205                 :             : {
     206                 :             :         bool enabled[warning_id_count];
     207                 :             : };
     208                 :             : 
     209                 :             : static autoarray<warnings_state> warnings_state_stack;
     210                 :             : static warnings_state main_warnings_state;
     211                 :             : 
     212                 :         290 : void push_warnings(bool warnings_command)
     213                 :             : {
     214                 :             :         warnings_state current_state;
     215                 :             : 
     216         [ +  + ]:        9280 :         for (int i = 0; i < (int)warning_id_count; ++i)
     217                 :             :         {
     218                 :        8990 :                 current_state.enabled[i] = asar_warnings[i].enabled;
     219                 :             :         }
     220                 :             : 
     221         [ +  + ]:         290 :         if (warnings_command)
     222                 :             :         {
     223                 :           9 :                 warnings_state_stack.append(current_state);
     224                 :             :         }
     225                 :             :         else
     226                 :             :         {
     227                 :         281 :                 main_warnings_state = current_state;
     228                 :             :         }
     229                 :         290 : }
     230                 :             : 
     231                 :         288 : void pull_warnings(bool warnings_command)
     232                 :             : {
     233   [ +  +  +  + ]:         288 :         if (warnings_state_stack.count > 0 || !warnings_command)
     234                 :             :         {
     235                 :             :                 warnings_state prev_state;
     236                 :             : 
     237         [ +  - ]:           6 :                 if (warnings_command)
     238                 :             :                 {
     239                 :           6 :                         prev_state = warnings_state_stack[warnings_state_stack.count - 1];
     240                 :             :                 }
     241                 :             :                 else
     242                 :             :                 {
     243                 :         279 :                         prev_state = main_warnings_state;
     244                 :             :                 }
     245                 :             : 
     246         [ +  + ]:        9120 :                 for (int i = 0; i < (int)warning_id_count; ++i)
     247                 :             :                 {
     248                 :        8835 :                         asar_warnings[i].enabled = prev_state.enabled[i];
     249                 :             :                 }
     250                 :             : 
     251         [ +  + ]:         285 :                 if (warnings_command)
     252                 :             :                 {
     253                 :           6 :                         warnings_state_stack.remove(warnings_state_stack.count - 1);
     254                 :             :                 }
     255                 :         285 :         }
     256                 :             :         else
     257                 :             :         {
     258                 :           3 :                 asar_throw_error(0, error_type_block, error_id_pullwarnings_without_pushwarnings);
     259                 :             :         }
     260                 :         285 : }
     261                 :             : 
     262                 :         279 : void verify_warnings()
     263                 :             : {
     264         [ +  + ]:         279 :         if (warnings_state_stack.count > 0)
     265                 :             :         {
     266                 :           3 :                 asar_throw_error(0, error_type_null, error_id_pushwarnings_without_pullwarnings);
     267                 :             : 
     268                 :           3 :                 warnings_state_stack.reset();
     269                 :             :         }
     270                 :         279 : }
        

Generated by: LCOV version 2.0-1