LCOV - code coverage report
Current view: top level - asar - interface-cli.cpp (source / functions) Coverage Total Hit
Test: asar.info Lines: 58.0 % 205 119
Test Date: 2024-01-15 16:26:31 Functions: 100.0 % 4 4
Branches: 36.6 % 246 90

             Branch data     Line data    Source code
       1                 :             : #include "asar.h"
       2                 :             : #include "assocarr.h"
       3                 :             : #include "libstr.h"
       4                 :             : #include "libcon.h"
       5                 :             : #include "libsmw.h"
       6                 :             : #include "errors.h"
       7                 :             : #include "warnings.h"
       8                 :             : #include "platform/file-helpers.h"
       9                 :             : #include "virtualfile.h"
      10                 :             : #include "interface-shared.h"
      11                 :             : #include "assembleblock.h"
      12                 :             : #include "asar_math.h"
      13                 :             : 
      14                 :             : #ifdef TIMELIMIT
      15                 :             : # if defined(linux)
      16                 :             : #  include <sys/resource.h>
      17                 :             : #  include <signal.h>
      18                 :             : # elif defined(_WIN32)
      19                 :             : //WARNING: The Windows equivalent of SIGXCPU, job limits, is very poorly suited for short-running
      20                 :             : // tasks like this; it's only checked approximately every seven seconds on the machine I tested on,
      21                 :             : // and it kills the process instantly once this happens. (Additionally, due to an implementation
      22                 :             : // quirk, it'll bug up if you ask for anything above about seven minutes, so don't do that.)
      23                 :             : #  include <windows.h>
      24                 :             : # else
      25                 :             : #  error Time limits not configured for this OS.
      26                 :             : # endif
      27                 :             : #endif
      28                 :             : 
      29                 :             : extern const char asarver[];
      30                 :             : 
      31                 :          16 : void print(const char * str)
      32                 :             : {
      33                 :          16 :         puts(str);
      34                 :          16 : }
      35                 :             : 
      36                 :             : static FILE * errloc=stderr;
      37                 :             : static int errnum=0;
      38                 :             : 
      39                 :         117 : void error_interface(int errid, int whichpass, const char * e_)
      40                 :             : {
      41                 :         117 :         errored = true;
      42         [ +  + ]:         117 :         if (pass == whichpass)
      43                 :             :         {
      44                 :          49 :                 errnum++;
      45                 :             :                 // don't show current block if the error came from an error command
      46   [ +  +  +  + ]:          49 :                 bool show_block = (thisblock && (errid != error_id_error_command));
      47   [ +  -  +  -  :         131 :                 fputs(STR getdecor() + "error: (" + get_error_name((asar_error_id)errid) + "): " + e_ + (show_block ? (STR" [" + thisblock + "]") : STR "") + "\n", errloc);
          +  -  +  +  +  
             +  -  -  -  
                      - ]
      48                 :             :                 static const int max_num_errors = 20;
      49         [ -  + ]:          49 :                 if (errnum == max_num_errors + 1) asar_throw_error(pass, error_type_fatal, error_id_limit_reached, max_num_errors);
      50                 :             :         }
      51                 :         117 : }
      52                 :             : 
      53                 :             : static bool werror=false;
      54                 :             : static bool warned=false;
      55                 :             : 
      56                 :          44 : void warn(int errid, const char * e_)
      57                 :             : {
      58                 :             :         // don't show current block if the warning came from a warn command
      59   [ +  +  +  + ]:          44 :         bool show_block = (thisblock && (errid != warning_id_warn_command));
      60   [ +  -  +  -  :         124 :         fputs(STR getdecor()+"warning: (" + get_warning_name((asar_warning_id)errid) + "): " + e_ + (show_block ? (STR" [" + thisblock + "]") : STR "") + "\n", errloc);
          +  -  +  +  +  
             +  -  -  -  
                      - ]
      61                 :          44 :         warned=true;
      62                 :          44 : }
      63                 :             : 
      64                 :             : #ifdef TIMELIMIT
      65                 :             : #if defined(linux)
      66                 :             : void onsigxcpu(int ignored)
      67                 :             : {
      68                 :             :         error<errnull>(pass, "Time limit exceeded.");
      69                 :             :         exit(1);
      70                 :             : }
      71                 :             : #elif defined(_WIN32)
      72                 :             : //null
      73                 :             : #endif
      74                 :             : #endif
      75                 :             : 
      76                 :             : 
      77                 :             : 
      78                 :          95 : int main(int argc, char * argv[])
      79                 :             : {
      80                 :             : #ifdef TIMELIMIT
      81                 :             : #if defined(linux)
      82                 :             :         rlimit lim;
      83                 :             :         lim.rlim_cur=TIMELIMIT;
      84                 :             :         lim.rlim_max=RLIM_INFINITY;
      85                 :             :         setrlimit(RLIMIT_CPU, &lim);
      86                 :             :         signal(SIGXCPU, onsigxcpu);
      87                 :             : #elif defined(_WIN32)
      88                 :             :         HANDLE hjob=CreateJobObject(NULL, nullptr);
      89                 :             :         AssignProcessToJobObject(hjob, GetCurrentProcess());
      90                 :             :         JOBOBJECT_BASIC_LIMIT_INFORMATION jbli;
      91                 :             :         jbli.LimitFlags=JOB_OBJECT_LIMIT_PROCESS_TIME;
      92                 :             :         jbli.PerProcessUserTimeLimit.LowPart=10*1000*1000*TIMELIMIT;
      93                 :             :         jbli.PerProcessUserTimeLimit.HighPart=0;
      94                 :             :         SetInformationJobObject(hjob, JobObjectBasicLimitInformation, &jbli, sizeof(jbli));
      95                 :             : #endif
      96                 :             : #endif
      97                 :             : #define pause(sev) do { if (pause>=pause_##sev) libcon_pause(); } while(0)
      98                 :             : 
      99                 :             :         enum {
     100                 :             :                 pause_no,
     101                 :             :                 pause_err,
     102                 :             :                 pause_warn,
     103                 :             :                 pause_yes,
     104                 :             :         } pause=pause_no;
     105                 :             : 
     106                 :             :         enum cmdlparam
     107                 :             :         {
     108                 :             :                 cmdlparam_none,
     109                 :             : 
     110                 :             :                 cmdlparam_addincludepath,
     111                 :             :                 cmdlparam_adddefine,
     112                 :             : 
     113                 :             :                 cmdlparam_count
     114                 :             :         };
     115                 :             : 
     116                 :             :         try
     117                 :             :         {
     118                 :          95 :                 romdata_r = nullptr;
     119   [ +  -  -  + ]:         190 :                 string version=STR"Asar "+dec(asarver_maj)+"."+dec(asarver_min)+((asarver_bug>=10 || asarver_min>=10)?".":"")+
     120         [ -  + ]:         285 :                                 dec(asarver_bug)+(asarver_beta?"pre":"")+", originally developed by Alcaro, maintained by Asar devs.\n"+
     121                 :             :                                 "Source code: https://github.com/RPGHacker/asar\n";
     122                 :          95 :                 char * myname=argv[0];
     123         [ +  - ]:          95 :                 if (strrchr(myname, '/')) myname=strrchr(myname, '/')+1;
     124                 :             :                 //char * dot=strrchr(myname, '.');
     125                 :             :                 //if (dot) *dot='\0';
     126         [ -  + ]:          95 :                 if (!strncasecmp(myname, "xkas", strlen("xkas"))) {
     127                 :             :                         // RPG Hacker: no asar_throw_Warning() here, because we didn't have a chance to disable warnings yet.
     128                 :             :                         // Also seems like warning aren't even registered at this point yet.
     129                 :           0 :                         puts("Warning: xkas support is being deprecated and will be removed in the next release of asar!!!");
     130                 :           0 :                         puts("(this was triggered by renaming asar.exe to xkas.exe, which activated a compatibility feature.)");
     131                 :           0 :                         errloc=stdout;
     132                 :             :                 }
     133                 :             :                 //if (dot) *dot='.';
     134         [ +  - ]:          95 :                 libcon_init(argc, argv,
     135                 :             :                         "[options] asm_file [rom_file]\n\n"
     136                 :             :                         "Supported options:\n\n"
     137                 :             :                         " --version         \n"
     138                 :             :                         "                   Display version information.\n\n"
     139                 :             :                         " -v, --verbose     \n"
     140                 :             :                         "                   Enable verbose mode.\n\n"
     141                 :             :                         " --symbols=<none/wla/nocash>\n"
     142                 :             :                         "                   Specifies the format of the symbols output file. (Default is none for no symbols file)\n\n"
     143                 :             :                         " --symbols-path=<filename>\n"
     144                 :             :                         "                   Override the default path to the symbols output file. The default is the ROM's base name with an\n"
     145                 :             :                         "                   extension of '.sym'.\n\n"
     146                 :             :                         " --no-title-check\n"
     147                 :             :                         "                   Disable verifying ROM title. (Note that irresponsible use will likely corrupt your ROM)\n\n"
     148                 :             :                         " --pause-mode=<never/on-error/on-warning/always>\n"
     149                 :             :                         "                   Specify when Asar should pause the application. (Never, on error, on warning or always)\n\n"
     150                 :             :                         " --fix-checksum=<on/off>\n"
     151                 :             :                         "                   Override Asar's checksum generation, allowing you to manually enable/disable generating a checksum\n\n"
     152                 :             :                         " -I<path>          \n"
     153                 :             :                         " --include <path>  \n"
     154                 :             :                         "                   Add an include search path to Asar.\n\n"
     155                 :             :                         " -D<def>[=<val>]   \n"
     156                 :             :                         " --define <def>[=<val>]\n"
     157                 :             :                         "                   Add a define (optionally with a value) to Asar.\n\n"
     158                 :             :                         " -werror           \n"
     159                 :             :                         "                   Treat warnings as errors.\n\n"
     160                 :             :                         " -w<ID>            \n"
     161                 :             :                         "                   Enable a specific warning.\n\n"
     162                 :             :                         " -wno<ID>          \n"
     163                 :             :                         "                   Disable a specific warning.\n\n"
     164                 :             :                         );
     165                 :          95 :                 ignoretitleerrors=false;
     166                 :          95 :                 string par;
     167                 :          95 :                 bool verbose=libcon_interactive;
     168                 :          95 :                 string symbols="";
     169                 :          95 :                 string symfilename="";
     170                 :             : 
     171                 :          95 :                 autoarray<string> includepaths;
     172                 :          95 :                 autoarray<const char*> includepath_cstrs;
     173                 :             : 
     174   [ +  -  +  + ]:         950 :                 while ((par=libcon_option()))
     175                 :             :                 {
     176                 :             :                         cmdlparam postprocess_param = cmdlparam_none;
     177                 :             :                         const char* postprocess_arg = nullptr;
     178                 :             : 
     179                 :             : #define checkstartmatch(arg, stringliteral) (!strncmp(arg, stringliteral, strlen(stringliteral)))
     180                 :             : 
     181         [ -  + ]:         380 :                         if (par=="--no-title-check") ignoretitleerrors=true;
     182   [ +  -  +  - ]:         380 :                         else if (par == "-v" || par=="--verbose") verbose=true;
     183         [ -  + ]:         380 :                         else if (checkstartmatch(par, "--symbols="))
     184                 :             :                         {
     185         [ #  # ]:           0 :                                 if (par == "--symbols=none") symbols = "";
     186         [ #  # ]:           0 :                                 else if (par=="--symbols=wla") symbols="wla";
     187         [ #  # ]:           0 :                                 else if (par=="--symbols=nocash") symbols="nocash";
     188                 :           0 :                                 else libcon_badusage();
     189                 :             :                         }
     190         [ -  + ]:         380 :                         else if (checkstartmatch(par, "--symbols-path=")) {
     191                 :           0 :                                 symfilename=((const char*)par) + strlen("--symbols-path=");
     192                 :             :                         }
     193         [ -  + ]:         380 :                         else if (par=="--version")
     194                 :             :                         {
     195                 :           0 :                                 puts(version);
     196                 :             :                                 return 0;
     197                 :             :                         }
     198         [ -  + ]:         380 :                         else if (checkstartmatch(par, "--pause-mode="))
     199                 :             :                         {
     200         [ #  # ]:           0 :                                 if (par=="--pause-mode=never") pause=pause_no;
     201         [ #  # ]:           0 :                                 else if (par=="--pause-mode=on-error") pause=pause_err;
     202         [ #  # ]:           0 :                                 else if (par=="--pause-mode=on-warning") pause=pause_warn;
     203         [ #  # ]:           0 :                                 else if (par=="--pause-mode=always") pause=pause_yes;
     204                 :           0 :                                 else libcon_badusage();
     205                 :             :                         }
     206         [ -  + ]:         380 :                         else if(checkstartmatch(par, "--fix-checksum=")) {
     207         [ #  # ]:           0 :                                 if(par=="--fix-checksum=on") {
     208                 :           0 :                                         force_checksum_fix = true;
     209                 :           0 :                                         checksum_fix_enabled = true;
     210         [ #  # ]:           0 :                                 } else if(par=="--fix-checksum=off") {
     211                 :           0 :                                         force_checksum_fix = true;
     212                 :           0 :                                         checksum_fix_enabled = false;
     213                 :           0 :                                 } else libcon_badusage();
     214                 :             :                         }
     215         [ +  + ]:         380 :                         else if (checkstartmatch(par, "-I"))
     216                 :             :                         {
     217                 :             :                                 postprocess_param = cmdlparam_addincludepath;
     218                 :          95 :                                 postprocess_arg = ((const char*)par) + strlen("-I");
     219                 :             :                         }
     220         [ +  + ]:         285 :                         else if (checkstartmatch(par, "-D"))
     221                 :             :                         {
     222                 :             :                                 postprocess_param = cmdlparam_adddefine;
     223                 :         190 :                                 postprocess_arg = ((const char*)par) + strlen("-D");
     224                 :             :                         }
     225         [ -  + ]:          95 :                         else if (par == "--include")
     226                 :             :                         {
     227                 :           0 :                                 postprocess_arg = libcon_option_value();
     228         [ #  # ]:           0 :                                 if (postprocess_arg != nullptr)
     229                 :             :                                 {
     230                 :             :                                         postprocess_param = cmdlparam_addincludepath;
     231                 :             :                                 }
     232                 :             :                         }
     233         [ +  - ]:          95 :                         else if (par == "--define")
     234                 :             :                         {
     235                 :          95 :                                 postprocess_arg = libcon_option_value();
     236         [ -  + ]:          95 :                                 if (postprocess_arg != nullptr)
     237                 :             :                                 {
     238                 :             :                                         postprocess_param = cmdlparam_adddefine;
     239                 :             :                                 }
     240                 :             :                         }
     241         [ #  # ]:           0 :                         else if (checkstartmatch(par, "-w"))
     242                 :             :                         {
     243                 :           0 :                                 const char* w_param = ((const char*)par) + strlen("-w");
     244                 :             : 
     245         [ #  # ]:           0 :                                 if (checkstartmatch(w_param, "error"))
     246                 :             :                                 {
     247                 :           0 :                                         werror = true;
     248                 :             :                                 }
     249         [ #  # ]:           0 :                                 else if (checkstartmatch(w_param, "no"))
     250                 :             :                                 {
     251                 :           0 :                                         asar_warning_id warnid = parse_warning_id_from_string(w_param + strlen("no"));
     252                 :             : 
     253         [ #  # ]:           0 :                                         if (warnid != warning_id_end)
     254                 :             :                                         {
     255                 :           0 :                                                 set_warning_enabled(warnid, false);
     256                 :             :                                         }
     257                 :             :                                         else
     258                 :             :                                         {
     259                 :           0 :                                                 asar_throw_error(pass, error_type_null, error_id_invalid_warning_id, "-wno", (int)(warning_id_start + 1), (int)(warning_id_end - 1));
     260                 :             :                                         }
     261                 :             :                                 }
     262                 :             :                                 else
     263                 :             :                                 {
     264                 :           0 :                                         asar_warning_id warnid = parse_warning_id_from_string(w_param);
     265                 :             : 
     266         [ #  # ]:           0 :                                         if (warnid != warning_id_end)
     267                 :             :                                         {
     268                 :           0 :                                                 set_warning_enabled(warnid, true);
     269                 :             :                                         }
     270                 :             :                                         else
     271                 :             :                                         {
     272                 :           0 :                                                 asar_throw_error(pass, error_type_null, error_id_invalid_warning_id, "-w", (int)(warning_id_start + 1), (int)(warning_id_end - 1));
     273                 :             :                                         }
     274                 :             :                                 }
     275                 :             : 
     276                 :             :                         }
     277                 :           0 :                         else libcon_badusage();
     278                 :             : 
     279         [ +  + ]:         380 :                         if (postprocess_param == cmdlparam_addincludepath)
     280                 :             :                         {
     281                 :          95 :                                 includepaths.append(postprocess_arg);
     282                 :             :                         }
     283         [ +  - ]:         285 :                         else if (postprocess_param == cmdlparam_adddefine)
     284                 :             :                         {
     285         [ +  + ]:         285 :                                 if (strchr(postprocess_arg, '=') != nullptr)
     286                 :             :                                 {
     287                 :             :                                         // argument contains value, not only name
     288                 :             :                                         const char* eq_loc = strchr(postprocess_arg, '=');
     289                 :         190 :                                         string name = string(postprocess_arg, (int)(eq_loc - postprocess_arg));
     290                 :         190 :                                         name = strip_whitespace(name);
     291         [ +  - ]:         190 :                                         name = strip_prefix(name, '!', false); // remove leading ! if present
     292                 :             : 
     293   [ +  -  -  +  :         190 :                                         if (!validatedefinename(name)) asar_throw_error(pass, error_type_null, error_id_cmdl_define_invalid, "command line defines", name.data());
                   -  - ]
     294                 :             : 
     295         [ -  + ]:         190 :                                         if (clidefines.exists(name)) {
     296                 :           0 :                                                 asar_throw_error(pass, error_type_null, error_id_cmdl_define_override, "Command line define", name.data());
     297                 :           0 :                                                 pause(err);
     298                 :             :                                                 return 1;
     299                 :             :                                         }
     300                 :         190 :                                         clidefines.create(name) = eq_loc + 1;
     301                 :         190 :                                 }
     302                 :             :                                 else
     303                 :             :                                 {
     304                 :             :                                         // argument doesn't have a value, only name
     305                 :          95 :                                         string name = postprocess_arg;
     306                 :          95 :                                         name = strip_whitespace(name);
     307         [ +  - ]:          95 :                                         name = strip_prefix(name, '!', false); // remove leading ! if present
     308                 :             : 
     309   [ +  -  -  +  :          95 :                                         if (!validatedefinename(name)) asar_throw_error(pass, error_type_null, error_id_cmdl_define_invalid, "command line defines", name.data());
                   -  - ]
     310                 :             : 
     311         [ -  + ]:          95 :                                         if (clidefines.exists(name)) {
     312                 :           0 :                                                 asar_throw_error(pass, error_type_null, error_id_cmdl_define_override, "Command line define", name.data());
     313                 :           0 :                                                 pause(err);
     314                 :             :                                                 return 1;
     315                 :             :                                         }
     316                 :          95 :                                         clidefines.create(name) = "";
     317                 :          95 :                                 }
     318                 :             :                         }
     319                 :             :                 }
     320         [ -  + ]:          95 :                 if (verbose)
     321                 :             :                 {
     322                 :           0 :                         puts(version);
     323                 :             :                 }
     324                 :          95 :                 string asmname=libcon_require_filename("Enter patch name:");
     325                 :          95 :                 string romname=libcon_optional_filename("Enter ROM name:", nullptr);
     326                 :             :                 //char * outname=libcon_optional_filename("Enter output ROM name:", nullptr);
     327                 :          95 :                 libcon_end();
     328   [ -  +  -  -  :          95 :                 if (!strchr(asmname, '.') && !file_exists(asmname)) asmname+=".asm";
                   -  - ]
     329         [ -  + ]:          95 :                 if (!romname)
     330                 :             :                 {
     331                 :           0 :                         string romnametmp = get_base_name(asmname);
     332   [ #  #  #  # ]:           0 :                         if (file_exists(romnametmp+".sfc")) romname=romnametmp+".sfc";
     333   [ #  #  #  # ]:           0 :                         else if (file_exists(romnametmp+".smc")) romname=romnametmp+".smc";
     334                 :           0 :                         else romname=STR romnametmp+".sfc";
     335                 :           0 :                 }
     336   [ -  +  -  -  :          95 :                 else if (!strchr(romname, '.') && !file_exists(romname))
                   -  - ]
     337                 :             :                 {
     338   [ #  #  #  # ]:           0 :                         if (file_exists(STR romname+".sfc")) romname+=".sfc";
     339   [ #  #  #  # ]:           0 :                         else if (file_exists(STR romname+".smc")) romname+=".smc";
     340                 :             :                 }
     341   [ +  -  -  + ]:          95 :                 if (!file_exists(romname))
     342                 :             :                 {
     343                 :           0 :                         FILE * f=fopen(romname, "wb");
     344         [ #  # ]:           0 :                         if (!f)
     345                 :             :                         {
     346                 :           0 :                                 asar_throw_error(pass, error_type_fatal, error_id_create_rom_failed);
     347                 :             :                         }
     348                 :           0 :                         fclose(f);
     349                 :             :                 }
     350   [ +  -  -  + ]:          95 :                 if (!openrom(romname, false))
     351                 :             :                 {
     352                 :             :                         thisfilename= nullptr;
     353                 :           0 :                         asar_throw_error(pass, error_type_null, openromerror);
     354                 :           0 :                         pause(err);
     355                 :           0 :                         return 1;
     356                 :             :                 }
     357                 :             :                 //check if the ROM title and checksum looks sane
     358   [ +  +  +  - ]:          95 :                 if (romlen>=32768 && !ignoretitleerrors)
     359                 :             :                 {
     360                 :          23 :                         bool validtitle=setmapper();
     361         [ -  + ]:          23 :                         if (!validtitle)
     362                 :             :                         {
     363                 :           0 :                                 string title;
     364         [ #  # ]:           0 :                                 for (int i=0;i<21;i++)
     365                 :             :                                 {
     366                 :           0 :                                         unsigned char c=romdata[snestopc(0x00FFC0+i)];
     367         [ #  # ]:           0 :                                         if (c==7) c=14;
     368         [ #  # ]:           0 :                                         if (c==8) c=27;//to not generate more hard-to-print characters than needed
     369         [ #  # ]:           0 :                                         if (c==9) c=26;//random characters are picked in accordance with the charset Windows-1252, but they should be garbage in all charsets
     370         [ #  # ]:           0 :                                         if (c=='\r') c=17;
     371         [ #  # ]:           0 :                                         if (c=='\n') c=25;
     372         [ #  # ]:           0 :                                         if (c=='\0') c=155;
     373                 :           0 :                                         title+=(char)c;
     374                 :             :                                 }
     375         [ #  # ]:           0 :                                 if (libcon_interactive)
     376                 :             :                                 {
     377   [ #  #  #  # ]:           0 :                                         if (!libcon_question_bool(STR"Warning: The ROM title appears to be \""+title+"\", which looks like garbage. "
     378                 :             :                                                         "Is this your ROM title? (Note that inproperly answering \"yes\" will crash your ROM.)", false))
     379                 :             :                                         {
     380                 :           0 :                                                 puts("Assembling aborted. snespurify should be able to fix your ROM.");
     381                 :             :                                                 return 1;
     382                 :             :                                         }
     383                 :             :                                 }
     384                 :             :                                 else
     385                 :             :                                 {
     386                 :           0 :                                         puts(STR"Error: The ROM title appears to be \""+title+"\", which looks like garbage. "
     387                 :             :                                                                 "If this is the ROM title, add --no-title-check to the command line options. If the ROM title is something else, use snespurify on your ROM.");
     388                 :           0 :                                         pause(err);
     389                 :           0 :                                         return 1;
     390                 :             :                                 }
     391                 :           0 :                         }
     392                 :             :                 }
     393                 :             : 
     394                 :         190 :                 string stdincludespath = STR dir(argv[0]) + "stdincludes.txt";
     395                 :          95 :                 parse_std_includes(stdincludespath, includepaths);
     396                 :             : 
     397         [ +  + ]:         285 :                 for (int i = 0; i < includepaths.count; ++i)
     398                 :             :                 {
     399                 :         190 :                         includepath_cstrs.append((const char*)includepaths[i]);
     400                 :             :                 }
     401                 :             : 
     402                 :          95 :                 size_t includepath_count = (size_t)includepath_cstrs.count;
     403                 :          95 :                 virtual_filesystem new_filesystem;
     404                 :          95 :                 new_filesystem.initialize(&includepath_cstrs[0], includepath_count);
     405                 :          95 :                 filesystem = &new_filesystem;
     406                 :             : 
     407                 :         190 :                 string stddefinespath = STR dir(argv[0]) + "stddefines.txt";
     408                 :          95 :                 parse_std_defines(stddefinespath);
     409                 :             : 
     410         [ +  + ]:         374 :                 for (pass=0;pass<3;pass++)
     411                 :             :                 {
     412                 :             :                         //pass 1: find which bank all labels are in, for label optimizations
     413                 :             :                         //  freespaces are listed as above 0xFFFFFF, to find if it's in the ROM or if it's dynamic
     414                 :             :                         //pass 2: find where exactly all labels are
     415                 :             :                         //pass 3: assemble it all
     416                 :         281 :                         initstuff();
     417                 :         281 :                         assemblefile(asmname, true);
     418                 :         279 :                         finishpass();
     419                 :             :                 }
     420                 :             : 
     421                 :          93 :                 closecachedfiles(); // this needs the vfs so do it before destroying it
     422                 :          93 :                 new_filesystem.destroy();
     423                 :          93 :                 filesystem = nullptr;
     424                 :             : 
     425   [ -  +  -  -  :          93 :                 if (werror && warned) asar_throw_error(pass, error_type_null, error_id_werror);
                   -  - ]
     426   [ +  +  +  - ]:          93 :                 if (checksum_fix_enabled) fixchecksum();
     427                 :             :                 //if (pcpos>romlen) romlen=pcpos;
     428         [ +  + ]:          93 :                 if (errored)
     429                 :             :                 {
     430                 :          20 :                         puts("Errors were detected while assembling the patch. Assembling aborted. Your ROM has not been modified.");
     431                 :          20 :                         closerom(false);
     432                 :          20 :                         reseteverything();
     433                 :          20 :                         pause(err);
     434                 :          20 :                         return 1;
     435                 :             :                 }
     436         [ +  + ]:          73 :                 if (warned)
     437                 :             :                 {
     438         [ -  + ]:          13 :                         if (libcon_interactive)
     439                 :             :                         {
     440   [ #  #  #  # ]:           0 :                                 if (!libcon_question_bool("One or more warnings were detected while assembling the patch. "
     441                 :             :                                                                                                                                         "Do you want insert the patch anyways? (Default: yes)", true))
     442                 :             :                                 {
     443                 :           0 :                                         puts("ROM left unchanged.");
     444                 :           0 :                                         closerom(false);
     445                 :           0 :                                         reseteverything();
     446                 :             :                                         return 1;
     447                 :             :                                 }
     448                 :             :                         }
     449                 :             :                         else
     450                 :             :                         {
     451   [ -  +  -  - ]:          13 :                                 if (verbose) puts("Assembling completed, but one or more warnings were detected.");
     452                 :          13 :                                 pause(warn);
     453                 :             :                         }
     454                 :             :                 }
     455                 :             :                 else
     456                 :             :                 {
     457   [ -  +  -  - ]:          60 :                         if (verbose) puts("Assembling completed without problems.");
     458                 :          60 :                         pause(yes);
     459                 :             :                 }
     460                 :          73 :                 unsigned int romCrc = closerom();
     461         [ -  + ]:          73 :                 if (symbols)
     462                 :             :                 {
     463   [ #  #  #  # ]:           0 :                         if (!symfilename) symfilename = get_base_name(romname)+".sym";
     464                 :           0 :                         string contents = create_symbols_file(symbols, romCrc);
     465                 :           0 :                         FILE * symfile = fopen(symfilename, "wt");
     466         [ #  # ]:           0 :                         if (!symfile)
     467                 :             :                         {
     468                 :           0 :                                 puts(STR"Failed to create symbols file: \"" + symfilename + "\".");
     469                 :           0 :                                 pause(err);
     470                 :             :                                 return 1;
     471                 :             :                         }
     472                 :             :                         else
     473                 :             :                         {
     474                 :           0 :                                 fputs(contents, symfile);
     475                 :           0 :                                 fclose(symfile);
     476                 :             :                         }
     477                 :           0 :                 }
     478                 :          73 :                 reseteverything();
     479                 :         135 :         }
     480                 :           2 :         catch(errfatal&)
     481                 :             :         {
     482                 :           2 :                 puts("A fatal error was detected while assembling the patch. Assembling aborted. Your ROM has not been modified.");
     483                 :           2 :                 closerom(false);
     484                 :           2 :                 reseteverything();
     485                 :           2 :                 pause(err);
     486                 :             :                 return 1;
     487                 :           2 :         }
     488                 :          73 :         return 0;
     489                 :             : }
        

Generated by: LCOV version 2.0-1