LCOV - code coverage report
Current view: top level - asar - libcon.cpp (source / functions) Coverage Total Hit
Test: asar build #66 Lines: 27.8 % 97 27
Test Date: 2024-01-16 02:45:19 Functions: 46.7 % 15 7
Branches: 14.9 % 74 11

             Branch data     Line data    Source code
       1                 :             : #include "libcon.h"
       2                 :             : #include "libstr.h"
       3                 :             : #include "unicode.h"
       4                 :             : #include <csignal>
       5                 :             : 
       6                 :             : #ifdef windows
       7                 :             : // for readconsole
       8                 :             : #include <windows.h>
       9                 :             : #endif
      10                 :             : 
      11                 :             : static const char * progname;
      12                 :             : static const char ** args;
      13                 :             : static int argsleft;
      14                 :             : bool libcon_interactive;
      15                 :             : static const char * usage;
      16                 :             : 
      17                 :             : static volatile bool confirmclose=true;
      18                 :           0 : void libcon_pause()
      19                 :             : {
      20         [ #  # ]:           0 :         if (confirmclose)
      21                 :             :         {
      22                 :           0 :                 confirmclose=false;
      23                 :             : #if defined(_WIN32)
      24                 :           0 :                 system("pause");
      25                 :             : #else
      26                 :           0 :                 printf("Press Enter to continue");
      27                 :           0 :                 getchar();
      28                 :             : #endif
      29                 :           0 :                 confirmclose=true;
      30                 :             :         }
      31                 :           0 : }
      32                 :             : 
      33                 :           0 : void libcon_badusage()
      34                 :             : {
      35                 :           0 :         printf("usage: %s %s", progname, usage);
      36                 :           0 :         exit(1);
      37                 :             : }
      38                 :             : 
      39                 :        2070 : static const char * getarg(bool tellusage, const char * defval= nullptr)
      40                 :             : {
      41         [ -  + ]:        2070 :         if (!argsleft)
      42                 :             :         {
      43         [ #  # ]:           0 :                 if (tellusage) libcon_badusage();
      44                 :           0 :                 return defval;
      45                 :             :         }
      46                 :        2070 :         args++;
      47                 :        2070 :         argsleft--;
      48                 :        2070 :         return args[0];
      49                 :             : }
      50                 :             : 
      51                 :           0 : void u8_fgets(char* buffer, int buffer_size, FILE* handle)
      52                 :             : {
      53                 :             : #if defined(windows)
      54                 :             :         // RPG Hacker: Using buffer_size * 2 here to account for potential surrogate pairs.
      55                 :             :         // The idea is that our buffer here should be able to at least hold the same amount
      56                 :             :         // of characters as the old ANSI version would have supported.
      57                 :           0 :         DWORD num_chars = buffer_size * 2;
      58                 :           0 :         wchar_t* w_buf = (wchar_t*)malloc(num_chars * sizeof(wchar_t));
      59                 :             :         // this was originally using fgetws, but it was broken on mingw for some
      60                 :             :         // weird reason. (or, more specifically, msvcrt.dll is broken. msvc itself
      61                 :             :         // doesn't use that one.)
      62                 :           0 :         BOOL res = ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), w_buf, num_chars-1, &num_chars, nullptr);
      63         [ #  # ]:           0 :         if(!res) { free(w_buf); return; }
      64                 :           0 :         w_buf[num_chars] = 0;
      65                 :             :         //(void)fgetws(w_buf, num_chars, stdin);
      66                 :           0 :         string u8_str;
      67   [ #  #  #  # ]:           0 :         if (utf16_to_utf8(&u8_str, w_buf))
      68                 :             :         {
      69                 :           0 :                 strncpy(buffer, u8_str, buffer_size);
      70                 :           0 :                 buffer[buffer_size-1] = '\0';
      71                 :             :                 // no point doing more than 1 since the next function cuts off input at the first newline anyways
      72         [ #  # ]:           0 :                 if(strchr(buffer, '\r')) *(strchr(buffer, '\r')) = '\n';
      73                 :             :         }
      74                 :           0 :         free(w_buf);
      75                 :             : #else
      76                 :           0 :         (void)fgets(buffer, buffer_size, handle);
      77                 :             : #endif
      78                 :           0 : }
      79                 :             : 
      80                 :           0 : static const char * requirestrfromuser(const char * question, bool filename)
      81                 :             : {
      82                 :           0 :         confirmclose=false;
      83                 :           0 :         char * rval=(char*)malloc(256);
      84                 :           0 :         *rval=0;
      85   [ #  #  #  # ]:           0 :         while (!strchr(rval, '\n') || *rval=='\n')
      86                 :             :         {
      87                 :           0 :                 *rval=0;
      88                 :           0 :                 printf("%s ", question);
      89                 :           0 :                 u8_fgets(rval, 250, stdin);
      90                 :             :         }
      91                 :           0 :         *strchr(rval, '\n')=0;
      92                 :           0 :         confirmclose=true;
      93                 :             : #ifdef _WIN32
      94   [ #  #  #  #  :           0 :         if (filename && rval[0]=='"' && rval[2]==':')
                   #  # ]
      95                 :             :         {
      96                 :           0 :                 char * rvalend=strchr(rval, '\0');
      97         [ #  # ]:           0 :                 if (rvalend[-1]=='"') rvalend[-1]='\0';
      98                 :           0 :                 return rval+1;
      99                 :             :         }
     100                 :             : #endif
     101                 :           0 :         return rval;
     102                 :             : }
     103                 :             : 
     104                 :           0 : static const char * requeststrfromuser(const char * question, bool filename, const char * defval)
     105                 :             : {
     106                 :           0 :         confirmclose=false;
     107                 :           0 :         char * rval=(char*)malloc(256);
     108                 :           0 :         *rval=0;
     109                 :           0 :         printf("%s ", question);
     110                 :           0 :         u8_fgets(rval, 250, stdin);
     111                 :           0 :         char *eol = strchr(rval, '\n');
     112         [ #  # ]:           0 :         if(!eol)
     113                 :             :         {
     114                 :           0 :                 printf("Unexpected end of input");
     115                 :           0 :                 exit(-1);
     116                 :             :         }
     117                 :           0 :         *eol = 0;
     118                 :           0 :         confirmclose=true;
     119         [ #  # ]:           0 :         if (!*rval) return defval;
     120                 :             : #ifdef _WIN32
     121   [ #  #  #  #  :           0 :         if (filename && rval[0]=='"' && rval[2]==':')
                   #  # ]
     122                 :             :         {
     123                 :           0 :                 char * rvalend=strchr(rval, '\0');
     124         [ #  # ]:           0 :                 if (rvalend[-1]=='"') rvalend[-1]='\0';
     125                 :           0 :                 return rval+1;
     126                 :             :         }
     127                 :             : #endif
     128                 :           0 :         return rval;
     129                 :             : }
     130                 :             : 
     131                 :         230 : void libcon_init(int argc, const char ** argv, const char * usage_)
     132                 :             : {
     133                 :         230 :         progname=argv[0];
     134                 :         230 :         args=argv;
     135                 :         230 :         argsleft=argc-1;
     136                 :         230 :         usage=usage_;
     137                 :         230 :         libcon_interactive=(!argsleft);
     138                 :             : #if defined(_WIN32)
     139         [ -  + ]:         115 :         if (libcon_interactive) atexit(libcon_pause);
     140                 :             : #endif
     141                 :         230 : }
     142                 :             : 
     143                 :         230 : const char * libcon_require_filename(const char * desc)
     144                 :             : {
     145         [ -  + ]:         230 :         if (libcon_interactive) return requirestrfromuser(desc, true);
     146                 :         230 :         else return getarg(true);
     147                 :             : }
     148                 :             : 
     149                 :           0 : const char * libcon_optional(const char * desc, const char * defval)
     150                 :             : {
     151         [ #  # ]:           0 :         if (libcon_interactive) return requeststrfromuser(desc, false, defval);
     152                 :           0 :         else return getarg(false, defval);
     153                 :             : }
     154                 :             : 
     155                 :         230 : const char * libcon_optional_filename(const char * desc, const char * defval)
     156                 :             : {
     157         [ -  + ]:         230 :         if (libcon_interactive) return requeststrfromuser(desc, true, defval);
     158                 :         230 :         else return getarg(false, defval);
     159                 :             : }
     160                 :             : 
     161                 :        1610 : const char * libcon_option()
     162                 :             : {
     163   [ +  -  +  -  :        1610 :         if (!libcon_interactive && argsleft && args[1][0]=='-') return getarg(false);
                   +  + ]
     164                 :         115 :         return nullptr;
     165                 :             : }
     166                 :             : 
     167                 :         230 : const char * libcon_option_value()
     168                 :             : {
     169         [ +  - ]:         230 :         if (!libcon_interactive) return getarg(false);
     170                 :           0 :         return nullptr;
     171                 :             : }
     172                 :             : 
     173                 :           0 : bool libcon_question_bool(const char * desc, bool defval)
     174                 :             : {
     175         [ #  # ]:           0 :         if (!libcon_interactive) return defval;
     176                 :             :         while (true)
     177                 :             :         {
     178         [ #  # ]:           0 :                 const char * answer=requeststrfromuser(desc, false, defval?"y":"n");
     179   [ #  #  #  #  :           0 :                 if (!stricmp(answer, "y") || !stricmp(answer, "yes")) return true;
                   #  # ]
     180   [ #  #  #  #  :           0 :                 if (!stricmp(answer, "n") || !stricmp(answer, "no")) return false;
                   #  # ]
     181                 :           0 :         }
     182                 :             : }
     183                 :             : 
     184                 :         230 : void libcon_end()
     185                 :             : {
     186   [ +  -  -  + ]:         230 :         if (!libcon_interactive && argsleft) libcon_badusage();
     187                 :         230 : }
        

Generated by: LCOV version 2.0-1