asar coverage - build #188


src/asar/
File: src/asar/libcon.cpp
Date: 2024-01-30 04:24:34
Lines:
27/96
28.1%
Functions:
7/15
46.7%
Branches:
11/74
14.9%

Line Branch Exec Source
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 void libcon_pause()
19 {
20 if (confirmclose)
21 {
22 confirmclose=false;
23 #if defined(_WIN32)
24 system("pause");
25 #else
26 printf("Press Enter to continue");
27 getchar();
28 #endif
29 confirmclose=true;
30 }
31 }
32
33 void libcon_badusage()
34 {
35 printf("usage: %s %s", progname, usage);
36 exit(1);
37 }
38
39 2214 static const char * getarg(bool tellusage, const char * defval= nullptr)
40 {
41
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2214 times.
2214 if (!argsleft)
42 {
43 if (tellusage) libcon_badusage();
44 return defval;
45 }
46 2214 args++;
47 2214 argsleft--;
48 2214 return args[0];
49 }
50
51 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 DWORD num_chars = buffer_size * 2;
58 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 BOOL res = ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), w_buf, num_chars-1, &num_chars, nullptr);
63 if(!res) { free(w_buf); return; }
64 w_buf[num_chars] = 0;
65 //(void)fgetws(w_buf, num_chars, stdin);
66 string u8_str;
67 if (utf16_to_utf8(&u8_str, w_buf))
68 {
69 strncpy(buffer, u8_str, buffer_size);
70 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 if(strchr(buffer, '\r')) *(strchr(buffer, '\r')) = '\n';
73 }
74 free(w_buf);
75 #else
76 (void)fgets(buffer, buffer_size, handle);
77 #endif
78 }
79
80 static const char * requirestrfromuser(const char * question, bool filename)
81 {
82 confirmclose=false;
83 char * rval=(char*)malloc(256);
84 *rval=0;
85 while (!strchr(rval, '\n') || *rval=='\n')
86 {
87 *rval=0;
88 printf("%s ", question);
89 u8_fgets(rval, 250, stdin);
90 }
91 *strchr(rval, '\n')=0;
92 confirmclose=true;
93 #ifdef _WIN32
94 if (filename && rval[0]=='"' && rval[2]==':')
95 {
96 char * rvalend=strchr(rval, '\0');
97 if (rvalend[-1]=='"') rvalend[-1]='\0';
98 return rval+1;
99 }
100 #endif
101 return rval;
102 }
103
104 static const char * requeststrfromuser(const char * question, bool filename, const char * defval)
105 {
106 confirmclose=false;
107 char * rval=(char*)malloc(256);
108 *rval=0;
109 printf("%s ", question);
110 u8_fgets(rval, 250, stdin);
111 char *eol = strchr(rval, '\n');
112 if(!eol)
113 {
114 printf("Unexpected end of input");
115 exit(-1);
116 }
117 *eol = 0;
118 confirmclose=true;
119 if (!*rval) return defval;
120 #ifdef _WIN32
121 if (filename && rval[0]=='"' && rval[2]==':')
122 {
123 char * rvalend=strchr(rval, '\0');
124 if (rvalend[-1]=='"') rvalend[-1]='\0';
125 return rval+1;
126 }
127 #endif
128 return rval;
129 }
130
131 246 void libcon_init(int argc, const char ** argv, const char * usage_)
132 {
133 246 progname=argv[0];
134 246 args=argv;
135 246 argsleft=argc-1;
136 246 usage=usage_;
137 246 libcon_interactive=(!argsleft);
138 #if defined(_WIN32)
139
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 123 times.
123 if (libcon_interactive) atexit(libcon_pause);
140 #endif
141 246 }
142
143 246 const char * libcon_require_filename(const char * desc)
144 {
145
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 246 times.
246 if (libcon_interactive) return requirestrfromuser(desc, true);
146 246 else return getarg(true);
147 }
148
149 const char * libcon_optional(const char * desc, const char * defval)
150 {
151 if (libcon_interactive) return requeststrfromuser(desc, false, defval);
152 else return getarg(false, defval);
153 }
154
155 246 const char * libcon_optional_filename(const char * desc, const char * defval)
156 {
157
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 246 times.
246 if (libcon_interactive) return requeststrfromuser(desc, true, defval);
158 246 else return getarg(false, defval);
159 }
160
161 1722 const char * libcon_option()
162 {
163
4/6
✓ Branch 0 taken 1722 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1722 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1476 times.
✓ Branch 5 taken 246 times.
1722 if (!libcon_interactive && argsleft && args[1][0]=='-') return getarg(false);
164 123 return nullptr;
165 }
166
167 246 const char * libcon_option_value()
168 {
169
1/2
✓ Branch 0 taken 246 times.
✗ Branch 1 not taken.
246 if (!libcon_interactive) return getarg(false);
170 return nullptr;
171 }
172
173 bool libcon_question_bool(const char * desc, bool defval)
174 {
175 if (!libcon_interactive) return defval;
176 while (true)
177 {
178 const char * answer=requeststrfromuser(desc, false, defval?"y":"n");
179 if (!stricmp(answer, "y") || !stricmp(answer, "yes")) return true;
180 if (!stricmp(answer, "n") || !stricmp(answer, "no")) return false;
181 }
182 }
183
184 246 void libcon_end()
185 {
186
2/4
✓ Branch 0 taken 246 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 246 times.
246 if (!libcon_interactive && argsleft) libcon_badusage();
187 246 }
188