asar coverage - build #241


src/asar/
File: src/asar/libcon.cpp
Date: 2025-02-21 03:13:54
Lines:
53/97
54.6%
Functions:
10/15
66.7%
Branches:
22/80
27.5%

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 2234 static const char * getarg(bool tellusage, const char * defval= nullptr)
40 {
41
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2234 times.
2234 if (!argsleft)
42 {
43 if (tellusage) libcon_badusage();
44 return defval;
45 }
46 2234 args++;
47 2234 argsleft--;
48 2234 return args[0];
49 }
50
51 2 bool 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 false; }
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 return true;
76 #else
77 2 char* out = fgets(buffer, buffer_size, handle);
78 2 return (out != NULL);
79 #endif
80 }
81
82 1 static const char * requirestrfromuser(const char * question, bool filename)
83 {
84 1 confirmclose=false;
85 1 char * rval=(char*)malloc(256);
86 1 *rval=0;
87
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
2 while (!strchr(rval, '\n') || *rval=='\n')
88 {
89 1 *rval=0;
90 1 printf("%s ", question);
91
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(!u8_fgets(rval, 250, stdin)) {
92 fprintf(stderr, "Unexpected end of input\n");
93 exit(1);
94 }
95 }
96 1 *strchr(rval, '\n')=0;
97 1 confirmclose=true;
98 #ifdef _WIN32
99 if (filename && rval[0]=='"' && rval[2]==':')
100 {
101 char * rvalend=strchr(rval, '\0');
102 if (rvalend[-1]=='"') rvalend[-1]='\0';
103 return rval+1;
104 }
105 #endif
106 1 return rval;
107 }
108
109 1 static const char * requeststrfromuser(const char * question, bool filename, const char * defval)
110 {
111 1 confirmclose=false;
112 1 char * rval=(char*)malloc(256);
113 1 *rval=0;
114 1 printf("%s ", question);
115
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(!u8_fgets(rval, 250, stdin)) return defval;
116 1 char *eol = strchr(rval, '\n');
117
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(!eol) return defval;
118 1 *eol = 0;
119 1 confirmclose=true;
120
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!*rval) return defval;
121 #ifdef _WIN32
122 if (filename && rval[0]=='"' && rval[2]==':')
123 {
124 char * rvalend=strchr(rval, '\0');
125 if (rvalend[-1]=='"') rvalend[-1]='\0';
126 return rval+1;
127 }
128 #endif
129 1 return rval;
130 }
131
132 250 void libcon_init(int argc, const char ** argv, const char * usage_)
133 {
134 250 progname=argv[0];
135 250 args=argv;
136 250 argsleft=argc-1;
137 250 usage=usage_;
138 250 libcon_interactive=(!argsleft);
139 #if defined(_WIN32)
140
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 124 times.
124 if (libcon_interactive) atexit(libcon_pause);
141 #endif
142 250 }
143
144 250 const char * libcon_require_filename(const char * desc)
145 {
146
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 249 times.
250 if (libcon_interactive) return requirestrfromuser(desc, true);
147 249 else return getarg(true);
148 }
149
150 const char * libcon_optional(const char * desc, const char * defval)
151 {
152 if (libcon_interactive) return requeststrfromuser(desc, false, defval);
153 else return getarg(false, defval);
154 }
155
156 250 const char * libcon_optional_filename(const char * desc, const char * defval)
157 {
158
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 249 times.
250 if (libcon_interactive) return requeststrfromuser(desc, true, defval);
159 249 else return getarg(false, defval);
160 }
161
162 1738 const char * libcon_option()
163 {
164
5/6
✓ Branch 0 taken 1737 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1737 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1488 times.
✓ Branch 5 taken 249 times.
1738 if (!libcon_interactive && argsleft && args[1][0]=='-') return getarg(false);
165 126 return nullptr;
166 }
167
168 248 const char * libcon_option_value()
169 {
170
1/2
✓ Branch 0 taken 248 times.
✗ Branch 1 not taken.
248 if (!libcon_interactive) return getarg(false);
171 return nullptr;
172 }
173
174 bool libcon_question_bool(const char * desc, bool defval)
175 {
176 if (!libcon_interactive) return defval;
177 while (true)
178 {
179 const char * answer=requeststrfromuser(desc, false, defval?"y":"n");
180 if (!stricmp(answer, "y") || !stricmp(answer, "yes")) return true;
181 if (!stricmp(answer, "n") || !stricmp(answer, "no")) return false;
182 }
183 }
184
185 250 void libcon_end()
186 {
187
3/4
✓ Branch 0 taken 249 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 249 times.
250 if (!libcon_interactive && argsleft) libcon_badusage();
188 250 }
189