123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- /*
- * Copyright (C) 2018 bzt (bztsrc@github)
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- */
- /**
- * minimal sprintf implementation
- */
- unsigned int vsprintf(char *dst, char* fmt, __builtin_va_list args)
- {
- long int arg;
- int len, sign, i;
- char *p, *orig=dst, tmpstr[19];
- // failsafes
- if(dst==(void*)0 || fmt==(void*)0) {
- return 0;
- }
- // main loop
- arg = 0;
- while(*fmt) {
- // argument access
- if(*fmt=='%') {
- fmt++;
- // literal %
- if(*fmt=='%') {
- goto put;
- }
- len=0;
- // size modifier
- while(*fmt>='0' && *fmt<='9') {
- len *= 10;
- len += *fmt-'0';
- fmt++;
- }
- // skip long modifier
- if(*fmt=='l') {
- fmt++;
- }
- // character
- if(*fmt=='c') {
- arg = __builtin_va_arg(args, int);
- *dst++ = (char)arg;
- fmt++;
- continue;
- } else
- // decimal number
- if(*fmt=='d') {
- arg = __builtin_va_arg(args, int);
- // check input
- sign=0;
- if((int)arg<0) {
- arg*=-1;
- sign++;
- }
- if(arg>99999999999999999L) {
- arg=99999999999999999L;
- }
- // convert to string
- i=18;
- tmpstr[i]=0;
- do {
- tmpstr[--i]='0'+(arg%10);
- arg/=10;
- } while(arg!=0 && i>0);
- if(sign) {
- tmpstr[--i]='-';
- }
- // padding, only space
- if(len>0 && len<18) {
- while(i>18-len) {
- tmpstr[--i]=' ';
- }
- }
- p=&tmpstr[i];
- goto copystring;
- } else
- // hex number
- if(*fmt=='x') {
- arg = __builtin_va_arg(args, long int);
- // convert to string
- i=16;
- tmpstr[i]=0;
- do {
- char n=arg & 0xf;
- // 0-9 => '0'-'9', 10-15 => 'A'-'F'
- tmpstr[--i]=n+(n>9?0x37:0x30);
- arg>>=4;
- } while(arg!=0 && i>0);
- // padding, only leading zeros
- if(len>0 && len<=16) {
- while(i>16-len) {
- tmpstr[--i]='0';
- }
- }
- p=&tmpstr[i];
- goto copystring;
- } else
- // string
- if(*fmt=='s') {
- p = __builtin_va_arg(args, char*);
- copystring: if(p==(void*)0) {
- p="(null)";
- }
- while(*p) {
- *dst++ = *p++;
- }
- }
- } else {
- put: *dst++ = *fmt;
- }
- fmt++;
- }
- *dst=0;
- // number of bytes written
- return dst-orig;
- }
- /**
- * Variable length arguments
- */
- unsigned int sprintf(char *dst, char* fmt, ...)
- {
- __builtin_va_list args;
- __builtin_va_start(args, fmt);
- return vsprintf(dst,fmt,args);
- }
|