#include "libwasm.h" size_t strlen (const char *s) { size_t l = 0; while (*s++) l++; return l; } char *strncpy (char *dst0, const char *src0, size_t count) { char *dscan; const char *sscan; dscan = dst0; sscan = src0; while (count > 0) { --count; if ((*dscan++ = *sscan++) == '\0') break; } while (count-- > 0) *dscan++ = '\0'; return dst0; } int strncmp (const char *s1, const char *s2, size_t n) { if (n == 0) return 0; while (n-- != 0 && *s1 == *s2) { if (n == 0 || *s1 == '\0') break; s1++; s2++; } return (* (unsigned char *) s1) - (* (unsigned char *) s2); } int strcmp (const char *s1, const char *s2) { while (*s1 != '\0' && *s1 == *s2) { s1++; s2++; } return (* (unsigned char *) s1) - (* (unsigned char *) s2); } void *memcpy (void *dest, const void *src, size_t n) { const char *s = (const char *) src; char *d = (char *) dest; int i; for (i=0; i 0) { num = PutUnsignedInt (pStr, fill, width, value / 10); pStr += num; } // Write filler characters else { while (width > 0) { PutChar (pStr, fill); pStr++; num++; width--; } } // Write lower digit num += PutChar (pStr, (value % 10) + '0'); return num; } ////------------------------------------------------------------------------------ /// Writes a signed int inside the given string, using the provided fill & width /// parameters. /// Returns the size of the written integer. /// \param pStr Storage string. /// \param fill Fill character. /// \param width Minimum integer width. /// \param value Signed integer value. ////------------------------------------------------------------------------------ static signed int PutSignedInt ( char *pStr, char fill, signed int width, signed int value) { signed int num = 0; unsigned int absolute; // Compute absolute value if (value < 0) { absolute = -value; } else { absolute = value; } // Take current digit into account when calculating width width--; // Recursively write upper digits if ( (absolute / 10) > 0) { if (value < 0) { num = PutSignedInt (pStr, fill, width, - (absolute / 10)); } else { num = PutSignedInt (pStr, fill, width, absolute / 10); } pStr += num; } else { // Reserve space for sign if (value < 0) { width--; } // Write filler characters while (width > 0) { PutChar (pStr, fill); pStr++; num++; width--; } // Write sign if (value < 0) { num += PutChar (pStr, '-'); pStr++; } } // Write lower digit num += PutChar (pStr, (absolute % 10) + '0'); return num; } //------------------------------------------------------------------------------ /// Writes an hexadecimal value into a string, using the given fill, width & /// capital parameters. /// Returns the number of char written. /// \param pStr Storage string. /// \param fill Fill character. /// \param width Minimum integer width. /// \param maj Indicates if the letters must be printed in lower- or upper-case. /// \param value Hexadecimal value. //------------------------------------------------------------------------------ static signed int PutHexa ( char *pStr, char fill, signed int width, unsigned char maj, unsigned int value) { signed int num = 0; // Decrement width width--; // Recursively output upper digits if ( (value >> 4) > 0) { num += PutHexa (pStr, fill, width, maj, value >> 4); pStr += num; } // Write filler chars else { while (width > 0) { PutChar (pStr, fill); pStr++; num++; width--; } } // Write current digit if ( (value & 0xF) < 10) { PutChar (pStr, (value & 0xF) + '0'); } else if (maj) { PutChar (pStr, (value & 0xF) - 10 + 'A'); } else { PutChar (pStr, (value & 0xF) - 10 + 'a'); } num++; return num; } static signed int PutPointer (char * pStr, void * ptr) { int num = PutString(pStr, "0x"); pStr += num; num += PutHexa(pStr, '0', 8, 0, (unsigned int) ptr); return num; } signed int vsnprintf (char *pStr, size_t length, const char *pFormat, va_list ap) { char fill; unsigned char width; signed int num = 0; signed int size = 0; // Clear the string if (pStr) { * pStr = 0; } // Phase string while (*pFormat != 0 && size < length) { // Normal character if (*pFormat != '%') { *pStr++ = *pFormat++; size++; } else if (* (pFormat + 1) == '%') { // Escaped '%' *pStr++ = '%'; pFormat += 2; size++; } else { // Token delimiter fill = ' '; width = 0; pFormat++; if (*pFormat == '0') { // Parse filler fill = '0'; pFormat++; } while ((*pFormat >= '0') && (*pFormat <= '9')) { // Parse width width = (width * 10) + *pFormat - '0'; pFormat++; } // Check if there is enough space if (size + width > length) { width = length - size; } // Parse type type_spec: switch (*pFormat) { case 'z': // modifikatory z,l jsou zbytečné - size long a int jsou stejne case 'l': pFormat++; goto type_spec; case 'd': case 'i': num = PutSignedInt (pStr, fill, width, va_arg (ap, signed int)); break; case 'u': num = PutUnsignedInt (pStr, fill, width, va_arg (ap, unsigned int)); break; case 'x': num = PutHexa (pStr, fill, width, 0, va_arg (ap, unsigned int)); break; case 'X': num = PutHexa (pStr, fill, width, 1, va_arg (ap, unsigned int)); break; case 's': num = PutString (pStr, va_arg (ap, char *)); break; case 'c': num = PutChar (pStr, va_arg (ap, unsigned int)); break; case 'p': num = PutPointer (pStr, va_arg (ap, void *)); break; default: return 0; } pFormat++; pStr += num; size += num; } } // NULL-terminated (final \0 is not counted) if (size < length) { *pStr = 0; } else { * (--pStr) = 0; size--; } return size; }