Exemplo n.º 1
0
/* Returns bytes written, negative on error */
int vfprintf(rd_t rd, char *fmt, va_list ap, int (*puts_fn)(rd_t,char*), int (*putc_fn)(rd_t,char)) {
    int total = 0;

    /* We buffer data here as long as possible, because the actual puts/putc functions tend to be slow
     * and the fewer calls we can make, the better. */
    char holding[32];
    int hold_count = 0;
    const int hold_len = sizeof(holding)/sizeof(holding[0]);

    holding[0] = '\0';

    int ret;

    while (*fmt) {
        if (*fmt == '%') {
            switch (*(++fmt)) {
                case 'x': {
                    /* Hex */
                    uint32_t hex = va_arg(ap, uint32_t);
                    char buf[12];

                    uitoa(hex, buf, 9, 16);

                    ret = holding_flush(holding, &hold_count, rd, puts_fn);
                    if (ret >= 0) {
                        total += ret;
                    }
                    else {
                        return ret;
                    }

                    ret = puts_fn(rd, buf);
                    if (ret >= 0) {
                        total += ret;
                    }
                    else {
                        return ret;
                    }

                    break;
                }
                case 'i': case 'd': {
                    int num = va_arg(ap, int);
                    char buf[9];    /* 7 digits in INT_MAX + '-' and '\0' */

                    itoa(num, buf, 12, 10);

                    ret = holding_flush(holding, &hold_count, rd, puts_fn);
                    if (ret >= 0) {
                        total += ret;
                    }
                    else {
                        return ret;
                    }

                    ret = puts_fn(rd, buf);
                    if (ret >= 0) {
                        total += ret;
                    }
                    else {
                        return ret;
                    }
                    break;
                }
                case 'u': {
                    uint32_t num = va_arg(ap, uint32_t);
                    char buf[9];    /* 7 digits in INT_MAX + '-' and '\0' */

                    uitoa(num, buf, 12, 10);

                    ret = holding_flush(holding, &hold_count, rd, puts_fn);
                    if (ret >= 0) {
                        total += ret;
                    }
                    else {
                        return ret;
                    }

                    ret = puts_fn(rd, buf);
                    if (ret >= 0) {
                        total += ret;
                    }
                    else {
                        return ret;
                    }
                    break;
                }
                case 'f': {
                    float num = (float) va_arg(ap, double);
                    char buf[20];

                    ftoa(num, 0.0001f, buf, 20);

                    ret = holding_flush(holding, &hold_count, rd, puts_fn);
                    if (ret >= 0) {
                        total += ret;
                    }
                    else {
                        return ret;
                    }

                    ret = puts_fn(rd, buf);
                    if (ret >= 0) {
                        total += ret;
                    }
                    else {
                        return ret;
                    }
                    break;
                }
                case 'c': {
                    char letter = (char) va_arg(ap, uint32_t);

                    ret = holding_push(letter, holding, hold_len, &hold_count, rd, puts_fn);
                    if (ret >= 0) {
                        total += ret;
                    }
                    else {
                        return ret;
                    }

                    break;
                }
                case 's': {
                    char *s = va_arg(ap, char*);

                    ret = holding_flush(holding, &hold_count, rd, puts_fn);
                    if (ret >= 0) {
                        total += ret;
                    }
                    else {
                        return ret;
                    }

                    ret = puts_fn(rd, s);
                    if (ret >= 0) {
                        total += ret;
                    }
                    else {
                        return ret;
                    }

                    break;
                }
                case '%': { /* Just print a % */
                    ret = holding_push('%', holding, hold_len, &hold_count, rd, puts_fn);
                    if (ret >= 0) {
                        total += ret;
                    }
                    else {
                        return ret;
                    }

                    break;
                }
                default: {
                    ret = holding_push('%', holding, hold_len, &hold_count, rd, puts_fn);
                    if (ret >= 0) {
                        total += ret;
                    }
                    else {
                        return ret;
                    }

                    ret = holding_push(*fmt, holding, hold_len, &hold_count, rd, puts_fn);
                    if (ret >= 0) {
                        total += ret;
                    }
                    else {
                        return ret;
                    }
                }
            }

            fmt++;
        }
        else {
            ret = holding_push(*fmt++, holding, hold_len, &hold_count, rd, puts_fn);
            if (ret >= 0) {
                total += ret;
            }
            else {
                return ret;
            }
        }
    }
Exemplo n.º 2
0
                    }
                    else {
                        return ret;
                    }
                }
            }

            fmt++;
        }
        else {
            ret = holding_push(*fmt++, holding, hold_len, &hold_count, dev);
            if (ret >= 0) {
                total += ret;
            }
            else {
                return ret;
            }
        }
    }

    ret = holding_flush(holding, &hold_count, dev);
    if (ret >= 0) {
        total += ret;
    }
    else {
        return ret;
    }

    return total;
}
Exemplo n.º 3
0
                    }
                    else {
                        return ret;
                    }
                }
            }

            fmt++;
        }
        else {
            ret = holding_push(*fmt++, holding, hold_len, &hold_count, rd, puts_fn);
            if (ret >= 0) {
                total += ret;
            }
            else {
                return ret;
            }
        }
    }

    ret = holding_flush(holding, &hold_count, rd, puts_fn);
    if (ret >= 0) {
        total += ret;
    }
    else {
        return ret;
    }

    return total;
}