mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-27 14:58:30 +00:00
Make improvements
- Fix build flakes - Polyfill SIGWINCH on Windows - Fix an execve issue on Windows - Make strerror show more information - Improve cmd.exe setup/teardown on Windows - Support bracketed paste mode in Blinkenlights - Show keyboard shortcuts in Blinkenlights status bar - Fixed copy_file_range() and copyfile() w/ zip filesystem - Size optimize GetDosArgv() to keep life.com 12kb in size - Improve Blinkenlights ability to load weird ELF executables - Fix program_executable_name and add GetInterpreterExecutableName - Make Python in tiny mode fail better if docstrings are requested - Update Python test exclusions in tiny* modes such as tinylinux - Add bulletproof unbreakable kprintf() troubleshooting function - Remove "oldskool" keyword from ape.S for virus scanners - Fix issue that caused backtraces to not print sometimes - Improve Blinkenlights serial uart character i/o - Make clock_gettime() not clobber errno on xnu - Improve sha256 cpuid check for old computers - Integrate some bestline linenoise fixes - Show runit process names better in htop - Remove SIGPIPE from ShowCrashReports() - Make realpath() not clobber errno - Avoid attaching GDB on non-Linux - Improve img.com example
This commit is contained in:
parent
2a938b3eaa
commit
b45d50b690
194 changed files with 4881 additions and 2966 deletions
|
@ -16,9 +16,7 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/bits/pushpop.h"
|
||||
#include "libc/bits/safemacros.internal.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
@ -32,25 +30,23 @@ struct DosArgv {
|
|||
wint_t wc;
|
||||
};
|
||||
|
||||
static textwindows noasan wint_t DecodeDosArgv(const char16_t **s) {
|
||||
textwindows noasan void DecodeDosArgv(int ignore, struct DosArgv *st) {
|
||||
wint_t x, y;
|
||||
for (;;) {
|
||||
if (!(x = *(*s)++)) break;
|
||||
if (IsUtf16Cont(x)) continue;
|
||||
if (IsUcs2(x)) {
|
||||
return x;
|
||||
} else {
|
||||
if ((y = *(*s)++)) {
|
||||
return MergeUtf16(x, y);
|
||||
if (!(x = *st->s++)) break;
|
||||
if (!IsUcs2(x)) {
|
||||
if ((y = *st->s++)) {
|
||||
x = MergeUtf16(x, y);
|
||||
} else {
|
||||
return 0;
|
||||
x = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return x;
|
||||
st->wc = x;
|
||||
}
|
||||
|
||||
static textwindows noasan void AppendDosArgv(struct DosArgv *st, wint_t wc) {
|
||||
static textwindows noasan void AppendDosArgv(wint_t wc, struct DosArgv *st) {
|
||||
uint64_t w;
|
||||
w = tpenc(wc);
|
||||
do {
|
||||
|
@ -59,6 +55,16 @@ static textwindows noasan void AppendDosArgv(struct DosArgv *st, wint_t wc) {
|
|||
} while (w >>= 8);
|
||||
}
|
||||
|
||||
static textwindows noasan int Count(int c, struct DosArgv *st) {
|
||||
int ignore, n = 0;
|
||||
asm("" : "=g"(ignore));
|
||||
while (st->wc == c) {
|
||||
DecodeDosArgv(ignore, st);
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tokenizes and transcodes Windows NT CLI args, thus avoiding
|
||||
* CommandLineToArgv() schlepping in forty megs of dependencies.
|
||||
|
@ -81,49 +87,60 @@ static textwindows noasan void AppendDosArgv(struct DosArgv *st, wint_t wc) {
|
|||
textwindows noasan int GetDosArgv(const char16_t *cmdline, char *buf,
|
||||
size_t size, char **argv, size_t max) {
|
||||
bool inquote;
|
||||
size_t i, argc, slashes, quotes;
|
||||
struct DosArgv st;
|
||||
st.s = cmdline;
|
||||
st.p = buf;
|
||||
st.pe = buf + size;
|
||||
int i, argc, slashes, quotes, ignore;
|
||||
static struct DosArgv st_;
|
||||
struct DosArgv *st = &st_;
|
||||
asm("" : "=g"(ignore));
|
||||
asm("" : "+r"(st));
|
||||
st->s = cmdline;
|
||||
st->p = buf;
|
||||
st->pe = buf + size;
|
||||
argc = 0;
|
||||
st.wc = DecodeDosArgv(&st.s);
|
||||
while (st.wc) {
|
||||
while (st.wc && (st.wc == ' ' || st.wc == '\t')) {
|
||||
st.wc = DecodeDosArgv(&st.s);
|
||||
DecodeDosArgv(ignore, st);
|
||||
while (st->wc) {
|
||||
while (st->wc && (st->wc == ' ' || st->wc == '\t')) {
|
||||
DecodeDosArgv(ignore, st);
|
||||
}
|
||||
if (!st.wc) break;
|
||||
if (!st->wc) break;
|
||||
if (++argc < max) {
|
||||
argv[argc - 1] = st.p < st.pe ? st.p : NULL;
|
||||
argv[argc - 1] = st->p < st->pe ? st->p : NULL;
|
||||
}
|
||||
inquote = false;
|
||||
while (st.wc) {
|
||||
if (!inquote && (st.wc == ' ' || st.wc == '\t')) break;
|
||||
if (st.wc == '"' || st.wc == '\\') {
|
||||
slashes = 0;
|
||||
quotes = 0;
|
||||
while (st.wc == '\\') st.wc = DecodeDosArgv(&st.s), slashes++;
|
||||
while (st.wc == '"') st.wc = DecodeDosArgv(&st.s), quotes++;
|
||||
while (st->wc) {
|
||||
if (!inquote && (st->wc == ' ' || st->wc == '\t')) break;
|
||||
if (st->wc == '"' || st->wc == '\\') {
|
||||
slashes = Count('\\', st);
|
||||
quotes = Count('"', st);
|
||||
if (!quotes) {
|
||||
while (slashes--) AppendDosArgv(&st, '\\');
|
||||
while (slashes--) {
|
||||
AppendDosArgv('\\', st);
|
||||
}
|
||||
} else {
|
||||
while (slashes >= 2) AppendDosArgv(&st, '\\'), slashes -= 2;
|
||||
if (slashes) AppendDosArgv(&st, '"'), quotes--;
|
||||
while (slashes >= 2) {
|
||||
AppendDosArgv('\\', st);
|
||||
slashes -= 2;
|
||||
}
|
||||
if (slashes) {
|
||||
AppendDosArgv('"', st);
|
||||
quotes--;
|
||||
}
|
||||
if (quotes > 0) {
|
||||
if (!inquote) quotes--;
|
||||
for (i = 3; i <= quotes + 1; i += 3) AppendDosArgv(&st, '"');
|
||||
for (i = 3; i <= quotes + 1; i += 3) {
|
||||
AppendDosArgv('"', st);
|
||||
}
|
||||
inquote = (quotes % 3 == 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
AppendDosArgv(&st, st.wc);
|
||||
st.wc = DecodeDosArgv(&st.s);
|
||||
AppendDosArgv(st->wc, st);
|
||||
DecodeDosArgv(ignore, st);
|
||||
}
|
||||
}
|
||||
AppendDosArgv(&st, '\0');
|
||||
AppendDosArgv('\0', st);
|
||||
}
|
||||
AppendDosArgv(&st, '\0');
|
||||
if (size) buf[min(st.p - buf, size - 1)] = '\0';
|
||||
AppendDosArgv('\0', st);
|
||||
if (size) buf[min(st->p - buf, size - 1)] = '\0';
|
||||
if (max) argv[min(argc, max - 1)] = NULL;
|
||||
return argc;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue