Skip to content

Commit

Permalink
Merge pull request #1065 from Dennisbonke/scanf
Browse files Browse the repository at this point in the history
options/ansi: Implement %m for do_scanf
  • Loading branch information
qookei authored May 27, 2024
2 parents 5075052 + cf019fe commit 45a3926
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 23 deletions.
56 changes: 33 additions & 23 deletions options/ansi/generic/stdio-stubs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -381,19 +381,32 @@ static int do_scanf(H &handler, const char *fmt, __builtin_va_list args) {
fmt++;
}

bool allocate_buf = false;
auto temp_dest = frg::string<MemoryAllocator>{getAllocator()};
int count = 0;

const auto append_to_buffer = [&](char c) {
if(allocate_buf) {
temp_dest += c;
count++;
} else {
char *typed_dest = (char *)dest;
if(typed_dest)
typed_dest[count++] = c;
}
};

int width = 0;
if (*fmt == '*') {
fmt++;
} else if (*fmt == '\'') {
/* TODO: numeric seperators locale stuff */
mlibc::infoLogger() << "do_scanf: \' not implemented!" << frg::endlog;
/* TODO: numeric seperators locale stuff */
mlibc::infoLogger() << "do_scanf: \' not implemented!" << frg::endlog;
fmt++;
continue;
} else if (*fmt == 'm') {
/* TODO: allocate buffer for them */
mlibc::infoLogger() << "do_scanf: m not implemented!" << frg::endlog;
allocate_buf = true;
fmt++;
continue;
} else if (*fmt >= '0' && *fmt <= '9') {
/* read in width specifier */
width = 0;
Expand Down Expand Up @@ -584,35 +597,27 @@ static int do_scanf(H &handler, const char *fmt, __builtin_va_list args) {
break;
}
case 's': {
char *typed_dest = (char *)dest;
char c = handler.look_ahead();
int count = 0;
EOF_CHECK(c == '\0');
while (c && !isspace(c)) {
handler.consume();
if (typed_dest)
typed_dest[count] = c;
append_to_buffer(c);
c = handler.look_ahead();
count++;
if (width && count >= width)
break;
}
NOMATCH_CHECK(count == 0);
if (typed_dest)
typed_dest[count] = '\0';
append_to_buffer('\0');
break;
}
case 'c': {
char *typed_dest = (char *)dest;
char c = handler.look_ahead();
EOF_CHECK(c == '\0');
int count = 0;
if (!width)
width = 1;
while (c && count < width) {
handler.consume();
if (typed_dest)
typed_dest[count] = c;
append_to_buffer(c);
c = handler.look_ahead();
count++;
}
Expand Down Expand Up @@ -648,22 +653,17 @@ static int do_scanf(H &handler, const char *fmt, __builtin_va_list args) {
scanset[1 + *fmt] = 1 - invert;
}

char *typed_dest = (char *)dest;
int count = 0;
char c = handler.look_ahead();
EOF_CHECK(c == '\0');
while (c && (!width || count < width)) {
handler.consume();
if (!scanset[1 + c])
break;
if (typed_dest)
typed_dest[count] = c;
append_to_buffer(c);
c = handler.look_ahead();
count++;
}
NOMATCH_CHECK(count == 0);
if (typed_dest)
typed_dest[count] = '\0';
append_to_buffer('\0');
break;
}
case 'p': {
Expand Down Expand Up @@ -709,6 +709,16 @@ static int do_scanf(H &handler, const char *fmt, __builtin_va_list args) {
continue;
}
}

if(allocate_buf && dest) {
char *temp = (char *)getAllocator().allocate(temp_dest.size() + 1);
memcpy(temp, temp_dest.data(), temp_dest.size());
temp[temp_dest.size()] = '\0';

char **dest_ptr = (char **)dest;
*dest_ptr = temp;
}

if (dest) match_count++;
}
return match_count;
Expand Down
10 changes: 10 additions & 0 deletions tests/ansi/sscanf.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
Expand Down Expand Up @@ -145,6 +146,15 @@ int main() {
assert(ret == EOF);
}

{
char *str = NULL;
int ret = sscanf("Managarm", "%ms", &str);
assert(ret == 1);
assert(str != NULL);
assert(!strcmp(str, "Managarm"));
free(str);
}

test_matrix();

return 0;
Expand Down

0 comments on commit 45a3926

Please sign in to comment.