asar coverage - build #196


src/asar/
File: src/asar/libcon.cpp
Date: 2024-01-31 02:50:38
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