summaryrefslogtreecommitdiff
path: root/riscv/riscv-probe/libfemto/std/vsnprintf.c
diff options
context:
space:
mode:
authorCarlos Maiolino <[email protected]>2025-07-10 22:18:39 +0200
committerCarlos Maiolino <[email protected]>2025-07-10 22:18:39 +0200
commit8c6fc0c15415b32080a848bbde640e104098cf13 (patch)
tree04a21bd28f9dc82c8e216390d6208ed93b9bcd11 /riscv/riscv-probe/libfemto/std/vsnprintf.c
Initial drop
Add some riscv code Signed-off-by: Carlos Maiolino <[email protected]>
Diffstat (limited to 'riscv/riscv-probe/libfemto/std/vsnprintf.c')
-rw-r--r--riscv/riscv-probe/libfemto/std/vsnprintf.c109
1 files changed, 109 insertions, 0 deletions
diff --git a/riscv/riscv-probe/libfemto/std/vsnprintf.c b/riscv/riscv-probe/libfemto/std/vsnprintf.c
new file mode 100644
index 0000000..32dcf3f
--- /dev/null
+++ b/riscv/riscv-probe/libfemto/std/vsnprintf.c
@@ -0,0 +1,109 @@
+// See LICENSE for license details.
+
+#include <stddef.h>
+#include <stdarg.h>
+
+int vsnprintf(char * out, size_t n, const char* s, va_list vl)
+{
+ int format = 0;
+ int longarg = 0;
+ size_t pos = 0;
+ for( ; *s; s++) {
+ if (format) {
+ switch(*s) {
+ case 'l': {
+ longarg = 1;
+ break;
+ }
+ case 'p': {
+ longarg = 1;
+ if (out && pos < n) {
+ out[pos] = '0';
+ }
+ pos++;
+ if (out && pos < n) {
+ out[pos] = 'x';
+ }
+ pos++;
+ }
+ case 'x': {
+ long num = longarg ? va_arg(vl, long) : va_arg(vl, int);
+ int hexdigits = 2*(longarg ? sizeof(long) : sizeof(int))-1;
+ for(int i = hexdigits; i >= 0; i--) {
+ int d = (num >> (4*i)) & 0xF;
+ if (out && pos < n) {
+ out[pos] = (d < 10 ? '0'+d : 'a'+d-10);
+ }
+ pos++;
+ }
+ longarg = 0;
+ format = 0;
+ break;
+ }
+ case 'd': {
+ long num = longarg ? va_arg(vl, long) : va_arg(vl, int);
+ if (num < 0) {
+ num = -num;
+ if (out && pos < n) {
+ out[pos] = '-';
+ }
+ pos++;
+ }
+ long digits = 1;
+ for (long nn = num; nn /= 10; digits++)
+ ;
+ for (int i = digits-1; i >= 0; i--) {
+ if (out && pos + i < n) {
+ out[pos + i] = '0' + (num % 10);
+ }
+ num /= 10;
+ }
+ pos += digits;
+ longarg = 0;
+ format = 0;
+ break;
+ }
+ case 's': {
+ const char* s2 = va_arg(vl, const char*);
+ while (*s2) {
+ if (out && pos < n) {
+ out[pos] = *s2;
+ }
+ pos++;
+ s2++;
+ }
+ longarg = 0;
+ format = 0;
+ break;
+ }
+ case 'c': {
+ if (out && pos < n) {
+ out[pos] = (char)va_arg(vl,int);
+ }
+ pos++;
+ longarg = 0;
+ format = 0;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ else if(*s == '%') {
+ format = 1;
+ }
+ else {
+ if (out && pos < n) {
+ out[pos] = *s;
+ }
+ pos++;
+ }
+ }
+ if (out && pos < n) {
+ out[pos] = 0;
+ }
+ else if (out && n) {
+ out[n-1] = 0;
+ }
+ return pos;
+}